METHOD(XonoticServerList, clickListBoxItem, void(entity, float, vector))
METHOD(XonoticServerList, resizeNotify, void(entity, vector, vector, vector, vector))
METHOD(XonoticServerList, keyDown, float(entity, float, float, float))
+ METHOD(XonoticServerList, toggleFavorite, void(entity, string))
ATTRIB(XonoticServerList, iconsSizeFactor, float, 0.85)
ATTRIB(XonoticServerList, ipAddressBox, entity, NULL)
ATTRIB(XonoticServerList, favoriteButton, entity, NULL)
ATTRIB(XonoticServerList, nextRefreshTime, float, 0)
- METHOD(XonoticServerList, refreshServerList, void(entity, float)) // refresh mode: 0 = just reparametrize, 1 = send new requests, 2 = clear
+ METHOD(XonoticServerList, refreshServerList, void(entity, float)) // refresh mode: REFRESHSERVERLIST_*
ATTRIB(XonoticServerList, needsRefresh, float, 1)
METHOD(XonoticServerList, focusEnter, void(entity))
METHOD(XonoticServerList, positionSortButton, void(entity, entity, float, float, string, void(entity, entity)))
ATTRIB(XonoticServerList, infoButton, entity, NULL)
ATTRIB(XonoticServerList, currentSortOrder, float, 0)
ATTRIB(XonoticServerList, currentSortField, float, -1)
+ ATTRIB(XonoticServerList, lastBumpSelectTime, float, 0)
ATTRIB(XonoticServerList, lastClickedServer, float, -1)
ATTRIB(XonoticServerList, lastClickedTime, float, 0)
entity makeXonoticServerList();
#ifndef IMPLEMENTATION
-var float autocvar_menu_serverlist_categories = TRUE;
-var float autocvar_menu_serverlist_categories_onlyifmultiple = TRUE;
-var float autocvar_menu_serverlist_purethreshold = 10;
-var string autocvar_menu_serverlist_recommended = "76.124.107.5:26004";
+var float autocvar_menu_slist_categories = TRUE;
+var float autocvar_menu_slist_categories_onlyifmultiple = TRUE;
+var float autocvar_menu_slist_purethreshold = 10;
+//var string autocvar_menu_slist_recommended = "76.124.107.5:26004";
// server cache fields
#define SLIST_FIELDS \
SLIST_FIELDS
#undef SLIST_FIELD
-// sort flags
-float SLSF_DESCENDING = 1;
-float SLSF_FAVORITES = 2;
-float SLSF_CATEGORIES = 4;
+const float REFRESHSERVERLIST_RESORT = 0; // sort the server list again to update for changes to e.g. favorite status, categories
+const float REFRESHSERVERLIST_REFILTER = 1; // ..., also update filter and sort criteria
+const float REFRESHSERVERLIST_ASK = 2; // ..., also suggest querying servers now
+const float REFRESHSERVERLIST_RESET = 3; // ..., also clear the list first
-float Get_Cat_Num_FromString(string input);
-entity Get_Cat_Ent(float catnum);
+// function declarations
+entity RetrieveCategoryEnt(float catnum);
float IsServerInList(string list, string srv);
#define IsFavorite(srv) IsServerInList(cvar_string("net_slist_favorites"), srv)
-#define IsRecommended(srv) IsServerInList(cvar_string("menu_serverlist_recommended"), srv) // todo: use update notification instead of cvar
+#define IsRecommended(srv) IsServerInList(_Nex_ExtResponseSystem_RecommendedServers, srv)
float CheckCategoryOverride(float cat);
float CheckCategoryForEntry(float entry);
-float m_getserverlistentrycategory(float entry) { return CheckCategoryOverride(CheckCategoryForEntry(entry)); }
+float m_gethostcachecategory(float entry) { return CheckCategoryOverride(CheckCategoryForEntry(entry)); }
+
+void RegisterSLCategories();
+
+void ServerList_Connect_Click(entity btn, entity me);
+void ServerList_Categories_Click(entity box, entity me);
+void ServerList_ShowEmpty_Click(entity box, entity me);
+void ServerList_ShowFull_Click(entity box, entity me);
+void ServerList_Filter_Change(entity box, entity me);
+void ServerList_Favorite_Click(entity btn, entity me);
+void ServerList_Info_Click(entity btn, entity me);
+void ServerList_Update_favoriteButton(entity btn, entity me);
// fields for category entities
#define MAX_CATEGORIES 9
float category_ent_count;
.string cat_name;
.string cat_string;
-.string cat_override_string;
-.float cat_override;
+.string cat_enoverride_string;
+.string cat_dioverride_string;
+.float cat_enoverride;
+.float cat_dioverride;
// fields for drawing categories
float category_name[MAX_CATEGORIES];
float category_item[MAX_CATEGORIES];
float category_draw_count;
-#define CATEGORIES \
- SLIST_CATEGORY(CAT_FAVORITED, "", "", _("Favorites")) \
- SLIST_CATEGORY(CAT_RECOMMENDED, "", "CAT_SERVERS", _("Recommended")) \
- SLIST_CATEGORY(CAT_NORMAL, "", "CAT_SERVERS", _("Normal Servers")) \
- SLIST_CATEGORY(CAT_SERVERS, "CAT_NORMAL", "CAT_SERVERS", _("Servers")) \
- SLIST_CATEGORY(CAT_XPM, "CAT_NORMAL", "CAT_SERVERS", _("Competitive Mode")) \
- SLIST_CATEGORY(CAT_MODIFIED, "", "CAT_SERVERS", _("Modified Servers")) \
- SLIST_CATEGORY(CAT_OVERKILL, "", "CAT_SERVERS", _("Overkill Mode")) \
- SLIST_CATEGORY(CAT_MINSTAGIB, "", "CAT_SERVERS", _("MinstaGib Mode")) \
- SLIST_CATEGORY(CAT_DEFRAG, "", "CAT_SERVERS", _("Defrag Mode"))
-
-// C is stupid, must use extra macro for concatenation
-#define SLIST_ADD_CAT_CVAR(name,default) var string autocvar_menu_serverlist_categories_##name##_override = default;
-#define SLIST_CATEGORY(name,enoverride,deoverride,string) \
- SLIST_ADD_CAT_CVAR(name, enoverride) \
+#define SLIST_CATEGORIES \
+ SLIST_CATEGORY(CAT_FAVORITED, "", "", ZCTX(_("SLCAT^Favorites"))) \
+ SLIST_CATEGORY(CAT_RECOMMENDED, "", "CAT_SERVERS", ZCTX(_("SLCAT^Recommended"))) \
+ SLIST_CATEGORY(CAT_NORMAL, "", "CAT_SERVERS", ZCTX(_("SLCAT^Normal Servers"))) \
+ SLIST_CATEGORY(CAT_SERVERS, "CAT_NORMAL", "CAT_SERVERS", ZCTX(_("SLCAT^Servers"))) \
+ SLIST_CATEGORY(CAT_XPM, "CAT_NORMAL", "CAT_SERVERS", ZCTX(_("SLCAT^Competitive Mode"))) \
+ SLIST_CATEGORY(CAT_MODIFIED, "", "CAT_SERVERS", ZCTX(_("SLCAT^Modified Servers"))) \
+ SLIST_CATEGORY(CAT_OVERKILL, "", "CAT_SERVERS", ZCTX(_("SLCAT^Overkill Mode"))) \
+ SLIST_CATEGORY(CAT_MINSTAGIB, "", "CAT_SERVERS", ZCTX(_("SLCAT^MinstaGib Mode"))) \
+ SLIST_CATEGORY(CAT_DEFRAG, "", "CAT_SERVERS", ZCTX(_("SLCAT^Defrag Mode")))
+
+#define SLIST_CATEGORY_AUTOCVAR(name) autocvar_menu_slist_categories_##name##_override
+#define SLIST_CATEGORY(name,enoverride,dioverride,str) \
float name; \
- void RegisterSLCategory_##name() \
- { \
+ var string SLIST_CATEGORY_AUTOCVAR(name) = enoverride;
+SLIST_CATEGORIES
+#undef SLIST_CATEGORY
+
+#endif
+#endif
+#ifdef IMPLEMENTATION
+
+void RegisterSLCategories()
+{
+ entity cat;
+ #define SLIST_CATEGORY(name,enoverride,dioverride,str) \
SET_FIELD_COUNT(name, CATEGORY_FIRST, category_ent_count) \
CHECK_MAX_COUNT(name, MAX_CATEGORIES, category_ent_count, "SLIST_CATEGORY") \
- entity cat = spawn(); \
+ cat = spawn(); \
categories[name - 1] = cat; \
cat.classname = "slist_category"; \
cat.cat_name = strzone(#name); \
- cat.cat_override_string = strzone((autocvar_menu_serverlist_categories ? \
- autocvar_menu_serverlist_categories_##name##_override \
- : \
- deoverride)); \
- cat.cat_string = strzone(string); \
- } \
- ACCUMULATE_FUNCTION(RegisterSLCategories, RegisterSLCategory_##name);
+ cat.cat_enoverride_string = strzone(SLIST_CATEGORY_AUTOCVAR(name)); \
+ cat.cat_dioverride_string = strzone(dioverride); \
+ cat.cat_string = strzone(str);
+ SLIST_CATEGORIES
+ #undef SLIST_CATEGORY
-CATEGORIES
-
-void RegisterSLCategories_Done()
-{
- float i, catnum;
+ float i, x, catnum;
string s;
- for(i = 0; i < category_ent_count; ++i)
- {
- s = categories[i].cat_override_string;
- if((s != "") && (s != categories[i].cat_name))
- {
- catnum = Get_Cat_Num_FromString(s);
- if(catnum)
- {
- strunzone(categories[i].cat_override_string);
- categories[i].cat_override = catnum;
- continue;
- }
+
+ #define PROCESS_OVERRIDE(override_string,override_field) \
+ for(i = 0; i < category_ent_count; ++i) \
+ { \
+ s = categories[i].override_string; \
+ if((s != "") && (s != categories[i].cat_name)) \
+ { \
+ catnum = 0; \
+ for(x = 0; x < category_ent_count; ++x) \
+ { if(categories[x].cat_name == s) { \
+ catnum = (x+1); \
+ break; \
+ } } \
+ if(catnum) \
+ { \
+ strunzone(categories[i].override_string); \
+ categories[i].override_field = catnum; \
+ continue; \
+ } \
+ else \
+ { \
+ print(sprintf( \
+ "RegisterSLCategories(): Improper override '%s' for category '%s'!\n", \
+ s, \
+ categories[i].cat_name \
+ )); \
+ } \
+ } \
+ strunzone(categories[i].override_string); \
+ categories[i].override_field = 0; \
}
- strunzone(categories[i].cat_override_string);
- categories[i].cat_override = 0;
- }
+ PROCESS_OVERRIDE(cat_enoverride_string, cat_enoverride)
+ PROCESS_OVERRIDE(cat_dioverride_string, cat_dioverride)
+ #undef PROCESS_OVERRIDE
}
-ACCUMULATE_FUNCTION(RegisterSLCategories, RegisterSLCategories_Done);
-
-#undef SLIST_ADD_CAT_CVAR
-#undef SLIST_CATEGORY
-#undef CATEGORIES
-
-void ServerList_Connect_Click(entity btn, entity me);
-void ServerList_ShowEmpty_Click(entity box, entity me);
-void ServerList_ShowFull_Click(entity box, entity me);
-void ServerList_Filter_Change(entity box, entity me);
-void ServerList_Favorite_Click(entity btn, entity me);
-void ServerList_Info_Click(entity btn, entity me);
-void ServerList_Update_favoriteButton(entity btn, entity me);
-
-#endif
-#endif
-#ifdef IMPLEMENTATION
// Supporting Functions
-float Get_Cat_Num_FromString(string input)
-{
- float i;
- for(i = 0; i < category_ent_count; ++i) { if(categories[i].cat_name == input) { return (i + 1); } }
- print(sprintf("Get_Cat_Num_FromString('%s'): Improper category name!\n", input));
- return 0;
-}
-entity Get_Cat_Ent(float catnum)
+entity RetrieveCategoryEnt(float catnum)
{
if((catnum > 0) && (catnum <= category_ent_count))
{
}
else
{
- error(sprintf("Get_Cat_Ent(%d): Improper category number!\n", catnum));
+ error(sprintf("RetrieveCategoryEnt(%d): Improper category number!\n", catnum));
return world;
}
}
-
float IsServerInList(string list, string srv)
{
string p;
float CheckCategoryOverride(float cat)
{
- entity catent = Get_Cat_Ent(cat);
+ entity catent = RetrieveCategoryEnt(cat);
if(catent)
{
- if(catent.cat_override) { return catent.cat_override; }
+ float override = (autocvar_menu_slist_categories ? catent.cat_enoverride : catent.cat_dioverride);
+ if(override) { return override; }
else { return cat; }
}
else
float CheckCategoryForEntry(float entry)
{
string s, k, v, modtype = "";
- float j, m, impure;
+ float j, m, impure = 0;
s = gethostcachestring(SLIST_FIELD_QCSTATUS, entry);
m = tokenizebyseparator(s, ":");
- //typestr = "";
- //if(m >= 2)
- //{
- // typestr = argv(0);
- // versionstr = argv(1);
- //}
- //freeslots = -1;
- //sflags = -1;
- //modname = "";
- impure = 0;
+
for(j = 2; j < m; ++j)
{
if(argv(j) == "")
else if(k == "M") { modtype = strtolower(v); }
}
- //print(sprintf("modtype = %s\n", modtype));
-
- if(impure > autocvar_menu_serverlist_purethreshold) { impure = TRUE; }
+ if(impure > autocvar_menu_slist_purethreshold) { impure = TRUE; }
else { impure = FALSE; }
if(gethostcachenumber(SLIST_FIELD_ISFAVORITE, entry)) { return CAT_FAVORITED; }
case "xpm": { return CAT_XPM; }
case "minstagib": { return CAT_MINSTAGIB; }
case "overkill": { return CAT_OVERKILL; }
+ //case "nix": { return CAT_NIX; }
+ //case "newtoys": { return CAT_NEWTOYS; }
// "cts" is allowed as compat, xdf is replacement
case "cts":
case "xdf": { return CAT_DEFRAG; }
- //if(modname != "CTS")
- //if(modname != "NIX")
- //if(modname != "NewToys")
-
default: { dprint(sprintf("Found strange mod type: %s\n", modtype)); return CAT_MODIFIED; }
}
}
return FALSE;
}
-float XonoticServerList_MapItems(float num)
+float CheckItemNumber(float num)
{
float i, n;
for(i = 0, n = 1; n <= category_draw_count; ++i, ++n)
{
- //print(sprintf("num: %d, i: %d, category_draw_count: %d, category_item[i]: %d\n", num, i, category_draw_count, category_item[i]));
- if(category_item[i] == (num - i)) { /*print("inserting cat... \\/\n");*/ return -category_name[i]; }
- else if(n == category_draw_count) { /*print("end item... \\/\n");*/ return (num - n); }
- else if((num - i) <= category_item[n]) { /*print("next item... \\/\n");*/ return (num - n); }
+ if(category_item[i] == (num - i)) { return -category_name[i]; }
+ else if(n == category_draw_count) { return (num - n); }
+ else if((num - i) <= category_item[n]) { return (num - n); }
}
// should never hit this point
- error("wtf XonoticServerList_MapItems fail?");
+ error(sprintf("CheckItemNumber(%d): Function fell through without normal return!\n", num));
return FALSE;
}
-void ToggleFavorite(string srv)
+void XonoticServerList_toggleFavorite(entity me, string srv)
{
string s, s0, s1, s2, srv_resolved, p;
float i, n, f;
cvar_set("net_slist_favorites", strcat(s, s1, srv));
}
- resorthostcache();
+ me.refreshServerList(me, REFRESHSERVERLIST_RESORT);
}
void ServerList_Update_favoriteButton(entity btn, entity me)
// clear list
me.nItems = 0;
+
+ // build categories
+ RegisterSLCategories();
}
void XonoticServerList_setSelected(entity me, float i)
{
if(me.nItems == 0)
return;
- //if(XonoticServerList_MapItems(gethostcachevalue(SLIST_HOSTCACHEVIEWCOUNT)) != me.nItems)
+ //if(gethostcachevalue(SLIST_HOSTCACHEVIEWCOUNT) != CheckItemNumber(me.nItems))
// { error("^1XonoticServerList_setSelected(); ERROR: ^7Host cache viewcount mismatches nItems!\n"); return; } // sorry, it would be wrong
- // todo: make this work somehow? ^
+ // ^ todo: make this work somehow?
+
+ #define SET_SELECTED_SERVER(cachenum) \
+ if(me.selectedServer) { strunzone(me.selectedServer); } \
+ me.selectedServer = strzone(gethostcachestring(SLIST_FIELD_CNAME, cachenum)); \
+ me.ipAddressBox.setText(me.ipAddressBox, me.selectedServer); \
+ me.ipAddressBox.cursorPos = strlen(me.selectedServer); \
+ me.ipAddressBoxFocused = -1; \
+ return;
- num = XonoticServerList_MapItems(me.selectedItem);
- if(num >= 0)
- {
- if(me.selectedServer)
- strunzone(me.selectedServer);
- me.selectedServer = strzone(gethostcachestring(SLIST_FIELD_CNAME, num));
+ num = CheckItemNumber(me.selectedItem);
- me.ipAddressBox.setText(me.ipAddressBox, me.selectedServer);
- me.ipAddressBox.cursorPos = strlen(me.selectedServer);
- me.ipAddressBoxFocused = -1;
+ if(num >= 0) { SET_SELECTED_SERVER(num); }
+ else if(save > me.selectedItem)
+ {
+ if(me.selectedItem == 0) { return; }
+ else
+ {
+ if(me.lastClickedTime >= me.lastBumpSelectTime)
+ {
+ SUPER(XonoticServerList).setSelected(me, me.selectedItem - 1);
+ num = CheckItemNumber(me.selectedItem);
+ if(num >= 0)
+ {
+ me.lastBumpSelectTime = time;
+ SET_SELECTED_SERVER(num);
+ }
+ }
+ }
+ }
+ else if(save < me.selectedItem)
+ {
+ if(me.selectedItem == me.nItems) { return; }
+ else
+ {
+ if(me.lastClickedTime >= me.lastBumpSelectTime)
+ {
+ SUPER(XonoticServerList).setSelected(me, me.selectedItem + 1);
+ num = CheckItemNumber(me.selectedItem);
+ if(num >= 0)
+ {
+ me.lastBumpSelectTime = time;
+ SET_SELECTED_SERVER(num);
+ }
+ }
+ }
}
}
+
void XonoticServerList_refreshServerList(entity me, float mode)
{
- // 0: just reparametrize
- // 1: also ask for new servers
- // 2: clear
//print("refresh of type ", ftos(mode), "\n");
- /* if(mode == 2) // borken
- {
- // clear list
- localcmd("net_slist\n");
- me.needsRefresh = 1; // net_slist kills sort order, so we need to restore it later
- }
- else */
-
- float m, i, n;
- float listflags = 0;
- string s, typestr, modstr;
- s = me.filterString;
- m = strstrofs(s, ":", 0);
- if(m >= 0)
+ if(mode >= REFRESHSERVERLIST_REFILTER)
{
- typestr = substring(s, 0, m);
- s = substring(s, m + 1, strlen(s) - m - 1);
- while(substring(s, 0, 1) == " ")
- s = substring(s, 1, strlen(s) - 1);
- }
- else
- typestr = "";
+ float m, i, n;
+ float listflags = 0;
+ string s, typestr, modstr;
- modstr = cvar_string("menu_slist_modfilter");
+ s = me.filterString;
- m = SLIST_MASK_AND - 1;
- resethostcachemasks();
+ m = strstrofs(s, ":", 0);
+ if(m >= 0)
+ {
+ typestr = substring(s, 0, m);
+ s = substring(s, m + 1, strlen(s) - m - 1);
+ while(substring(s, 0, 1) == " ")
+ s = substring(s, 1, strlen(s) - 1);
+ }
+ else
+ typestr = "";
- // ping: reject negative ping (no idea why this happens in the first place, engine bug)
- sethostcachemasknumber(++m, SLIST_FIELD_PING, 0, SLIST_TEST_GREATEREQUAL);
+ modstr = cvar_string("menu_slist_modfilter");
- // show full button
- if(!me.filterShowFull)
- {
- sethostcachemasknumber(++m, SLIST_FIELD_FREESLOTS, 1, SLIST_TEST_GREATEREQUAL); // legacy
- sethostcachemaskstring(++m, SLIST_FIELD_QCSTATUS, ":S0:", SLIST_TEST_NOTCONTAIN); // g_maxplayers support
- }
+ m = SLIST_MASK_AND - 1;
+ resethostcachemasks();
- // show empty button
- if(!me.filterShowEmpty)
- sethostcachemasknumber(++m, SLIST_FIELD_NUMHUMANS, 1, SLIST_TEST_GREATEREQUAL);
+ // ping: reject negative ping (no idea why this happens in the first place, engine bug)
+ sethostcachemasknumber(++m, SLIST_FIELD_PING, 0, SLIST_TEST_GREATEREQUAL);
- // gametype filtering
- if(typestr != "")
- sethostcachemaskstring(++m, SLIST_FIELD_QCSTATUS, strcat(typestr, ":"), SLIST_TEST_STARTSWITH);
+ // show full button
+ if(!me.filterShowFull)
+ {
+ sethostcachemasknumber(++m, SLIST_FIELD_FREESLOTS, 1, SLIST_TEST_GREATEREQUAL); // legacy
+ sethostcachemaskstring(++m, SLIST_FIELD_QCSTATUS, ":S0:", SLIST_TEST_NOTCONTAIN); // g_maxplayers support
+ }
- // mod filtering
- if(modstr != "")
- {
- if(substring(modstr, 0, 1) == "!")
- sethostcachemaskstring(++m, SLIST_FIELD_MOD, resolvemod(substring(modstr, 1, strlen(modstr) - 1)), SLIST_TEST_NOTEQUAL);
- else
- sethostcachemaskstring(++m, SLIST_FIELD_MOD, resolvemod(modstr), SLIST_TEST_EQUAL);
- }
+ // show empty button
+ if(!me.filterShowEmpty)
+ sethostcachemasknumber(++m, SLIST_FIELD_NUMHUMANS, 1, SLIST_TEST_GREATEREQUAL);
- // server banning
- n = tokenizebyseparator(_Nex_ExtResponseSystem_BannedServers, " ");
- for(i = 0; i < n; ++i)
- if(argv(i) != "")
- sethostcachemaskstring(++m, SLIST_FIELD_CNAME, argv(i), SLIST_TEST_NOTSTARTSWITH);
+ // gametype filtering
+ if(typestr != "")
+ sethostcachemaskstring(++m, SLIST_FIELD_QCSTATUS, strcat(typestr, ":"), SLIST_TEST_STARTSWITH);
- m = SLIST_MASK_OR - 1;
- if(s != "")
- {
- sethostcachemaskstring(++m, SLIST_FIELD_NAME, s, SLIST_TEST_CONTAINS);
- sethostcachemaskstring(++m, SLIST_FIELD_MAP, s, SLIST_TEST_CONTAINS);
- sethostcachemaskstring(++m, SLIST_FIELD_PLAYERS, s, SLIST_TEST_CONTAINS);
- sethostcachemaskstring(++m, SLIST_FIELD_QCSTATUS, strcat(s, ":"), SLIST_TEST_STARTSWITH);
- }
+ // mod filtering
+ if(modstr != "")
+ {
+ if(substring(modstr, 0, 1) == "!")
+ sethostcachemaskstring(++m, SLIST_FIELD_MOD, resolvemod(substring(modstr, 1, strlen(modstr) - 1)), SLIST_TEST_NOTEQUAL);
+ else
+ sethostcachemaskstring(++m, SLIST_FIELD_MOD, resolvemod(modstr), SLIST_TEST_EQUAL);
+ }
- // sorting flags
- //listflags |= SLSF_FAVORITES;
- listflags |= SLSF_CATEGORIES;
- if(me.currentSortOrder < 0) { listflags |= SLSF_DESCENDING; }
- sethostcachesort(me.currentSortField, listflags);
+ // server banning
+ n = tokenizebyseparator(_Nex_ExtResponseSystem_BannedServers, " ");
+ for(i = 0; i < n; ++i)
+ if(argv(i) != "")
+ sethostcachemaskstring(++m, SLIST_FIELD_CNAME, argv(i), SLIST_TEST_NOTSTARTSWITH);
+
+ m = SLIST_MASK_OR - 1;
+ if(s != "")
+ {
+ sethostcachemaskstring(++m, SLIST_FIELD_NAME, s, SLIST_TEST_CONTAINS);
+ sethostcachemaskstring(++m, SLIST_FIELD_MAP, s, SLIST_TEST_CONTAINS);
+ sethostcachemaskstring(++m, SLIST_FIELD_PLAYERS, s, SLIST_TEST_CONTAINS);
+ sethostcachemaskstring(++m, SLIST_FIELD_QCSTATUS, strcat(s, ":"), SLIST_TEST_STARTSWITH);
+ }
+
+ // sorting flags
+ //listflags |= SLSF_FAVORITES;
+ listflags |= SLSF_CATEGORIES;
+ if(me.currentSortOrder < 0) { listflags |= SLSF_DESCENDING; }
+ sethostcachesort(me.currentSortField, listflags);
+ }
resorthostcache();
- if(mode >= 1) { refreshhostcache(); }
+ if(mode >= REFRESHSERVERLIST_ASK)
+ refreshhostcache(mode >= REFRESHSERVERLIST_RESET);
}
void XonoticServerList_focusEnter(entity me)
{
return;
}
me.nextRefreshTime = time + 10;
- me.refreshServerList(me, 1);
+ me.refreshServerList(me, REFRESHSERVERLIST_ASK);
}
void XonoticServerList_draw(entity me)
_Nex_ExtResponseSystem_BannedServersNeedsRefresh = 0;
}
+ if(_Nex_ExtResponseSystem_RecommendedServersNeedsRefresh)
+ {
+ if(!me.needsRefresh)
+ me.needsRefresh = 3;
+ _Nex_ExtResponseSystem_RecommendedServersNeedsRefresh = 0;
+ }
+
if(me.currentSortField == -1)
{
me.setSortOrder(me, SLIST_FIELD_PING, +1);
- me.refreshServerList(me, 2);
+ me.refreshServerList(me, REFRESHSERVERLIST_RESET);
}
else if(me.needsRefresh == 1)
{
else if(me.needsRefresh == 2)
{
me.needsRefresh = 0;
- me.refreshServerList(me, 0);
+ me.refreshServerList(me, REFRESHSERVERLIST_REFILTER);
+ }
+ else if(me.needsRefresh == 3)
+ {
+ me.needsRefresh = 0;
+ me.refreshServerList(me, REFRESHSERVERLIST_RESORT);
}
owned = ((me.selectedServer == me.ipAddressBox.text) && (me.ipAddressBox.text != ""));
for(i = 0; i < category_draw_count; ++i) { category_name[i] = -1; category_item[i] = -1; }
category_draw_count = 0;
- if(autocvar_menu_serverlist_categories >= 0) // if less than 0, don't even draw a category heading for favorites
+ if(autocvar_menu_slist_categories >= 0) // if less than 0, don't even draw a category heading for favorites
{
float itemcount = gethostcachevalue(SLIST_HOSTCACHEVIEWCOUNT);
me.nItems = itemcount;
// entire list, otherwise there is no way to know which item is first in its category.
float cat, x;
- for(i = 0; i < itemcount; ++i)
+ for(i = 0; i < itemcount; ++i) // FIXME this loop is TOTALLY unacceptable (O(servers)). Make it O(categories * log(servers)). Yes, that is possible.
{
cat = gethostcachenumber(SLIST_FIELD_CATEGORY, i);
if(cat)
}
}
}
- if(autocvar_menu_serverlist_categories_onlyifmultiple && (category_draw_count == 1))
+ if(autocvar_menu_slist_categories_onlyifmultiple && (category_draw_count == 1))
{
- category_name[0] = category_name[1] = -1;
- category_item[0] = category_item[1] = -1;
+ category_name[0] = -1;
+ category_item[0] = -1;
category_draw_count = 0;
me.nItems = itemcount;
}
{
for(i = 0; i < me.nItems; ++i)
{
- num = XonoticServerList_MapItems(i);
+ num = CheckItemNumber(i);
if(num >= 0)
{
if(gethostcachestring(SLIST_FIELD_CNAME, num) == me.selectedServer)
if(me.selectedItem >= me.nItems) { me.selectedItem = me.nItems - 1; }
if(me.selectedServer) { strunzone(me.selectedServer); }
- num = XonoticServerList_MapItems(me.selectedItem);
+ num = CheckItemNumber(me.selectedItem);
if(num >= 0) { me.selectedServer = strzone(gethostcachestring(SLIST_FIELD_CNAME, num)); }
}
}
me.filterString = strzone(box.text);
else
me.filterString = string_null;
- me.refreshServerList(me, 0);
+ me.refreshServerList(me, REFRESHSERVERLIST_REFILTER);
+
+ me.ipAddressBox.setText(me.ipAddressBox, "");
+ me.ipAddressBox.cursorPos = 0;
+ me.ipAddressBoxFocused = -1;
+}
+void ServerList_Categories_Click(entity box, entity me)
+{
+ box.setChecked(box, autocvar_menu_slist_categories = !autocvar_menu_slist_categories);
+ ///refreshhostcache(TRUE);
+
+ //cvar_set("net_slist_pause", "0");
+ //Destroy_Category_Entities();
+ //CALL_ACCUMULATED_FUNCTION(RegisterSLCategories);
+ //me.refreshServerList(me, REFRESHSERVERLIST_REFILTER);
+
+ me.refreshServerList(me, REFRESHSERVERLIST_RESORT);
me.ipAddressBox.setText(me.ipAddressBox, "");
me.ipAddressBox.cursorPos = 0;
void ServerList_ShowEmpty_Click(entity box, entity me)
{
box.setChecked(box, me.filterShowEmpty = !me.filterShowEmpty);
- me.refreshServerList(me, 0);
+ me.refreshServerList(me, REFRESHSERVERLIST_REFILTER);
me.ipAddressBox.setText(me.ipAddressBox, "");
me.ipAddressBox.cursorPos = 0;
void ServerList_ShowFull_Click(entity box, entity me)
{
box.setChecked(box, me.filterShowFull = !me.filterShowFull);
- me.refreshServerList(me, 0);
+ me.refreshServerList(me, REFRESHSERVERLIST_REFILTER);
me.ipAddressBox.setText(me.ipAddressBox, "");
me.ipAddressBox.cursorPos = 0;
if(me.selectedServer)
strunzone(me.selectedServer);
me.selectedServer = string_null;
- me.refreshServerList(me, 0);
+ me.refreshServerList(me, REFRESHSERVERLIST_REFILTER);
}
void XonoticServerList_positionSortButton(entity me, entity btn, float theOrigin, float theSize, string theTitle, void(entity, entity) theFunc)
{
ipstr = netaddress_resolve(me.ipAddressBox.text, 26000);
if(ipstr != "")
{
- ToggleFavorite(me.ipAddressBox.text);
+ me.toggleFavorite(me, me.ipAddressBox.text);
me.ipAddressBoxFocused = -1;
}
}
void ServerList_Info_Click(entity btn, entity me)
{
- main.serverInfoDialog.loadServerInfo(main.serverInfoDialog, XonoticServerList_MapItems(me.selectedItem));
+ main.serverInfoDialog.loadServerInfo(main.serverInfoDialog, CheckItemNumber(me.selectedItem));
DialogOpenButton_Click(me, main.serverInfoDialog);
}
void XonoticServerList_clickListBoxItem(entity me, float i, vector where)
{
- float num = XonoticServerList_MapItems(i);
- if(num == me.lastClickedServer)
- if(time < me.lastClickedTime + 0.3)
- {
- // DOUBLE CLICK!
- ServerList_Connect_Click(NULL, me);
- }
- me.lastClickedServer = num;
- me.lastClickedTime = time;
+ float num = CheckItemNumber(i);
+ if(num >= 0)
+ {
+ if(num == me.lastClickedServer)
+ if(time < me.lastClickedTime + 0.3)
+ {
+ // DOUBLE CLICK!
+ ServerList_Connect_Click(NULL, me);
+ }
+ me.lastClickedServer = num;
+ me.lastClickedTime = time;
+ }
}
void XonoticServerList_drawListBoxItem(entity me, float i, vector absSize, float isSelected)
{
float m, pure, freeslots, j, sflags;
string s, typestr, versionstr, k, v, modname;
- float item = XonoticServerList_MapItems(i);
+ float item = CheckItemNumber(i);
//print(sprintf("time: %f, i: %d, item: %d, nitems: %d\n", time, i, item, me.nItems));
if(item < 0)
{
- entity catent = Get_Cat_Ent(-item);
- if(catent) { draw_Text(me.realUpperMargin * eY + (me.columnNameOrigin + (me.columnNameSize - draw_TextWidth(catent.cat_string, 0, me.realFontSize)) * 0.5) * eX, catent.cat_string, me.realFontSize, '1 1 1', SKINALPHA_TEXT, 0); return; }
+ entity catent = RetrieveCategoryEnt(-item);
+ if(catent)
+ {
+ draw_Text(
+ eY * me.realUpperMargin
+ +
+ eX * (me.columnNameOrigin + (me.columnNameSize - draw_TextWidth(catent.cat_string, 0, me.realFontSize)) * 0.5),
+ catent.cat_string,
+ me.realFontSize,
+ '1 1 1',
+ SKINALPHA_TEXT,
+ 0
+ );
+ return;
+ }
}
if(isSelected)
float XonoticServerList_keyDown(entity me, float scan, float ascii, float shift)
{
- float i = XonoticServerList_MapItems(me.selectedItem);
+ float i = CheckItemNumber(me.selectedItem);
vector org, sz;
org = boxToGlobal(eY * (me.selectedItem * me.itemHeight - me.scrollPos), me.origin, me.size);
sz = boxToGlobalSize(eY * me.itemHeight + eX * (1 - me.controlWidth), me.size);
+ me.lastBumpSelectTime = 0;
+
if(scan == K_ENTER || scan == K_KP_ENTER)
{
ServerList_Connect_Click(NULL, me);
{
if((me.nItems != 0) && (i >= 0))
{
- ToggleFavorite(me.selectedServer);
+ me.toggleFavorite(me, me.selectedServer);
me.ipAddressBoxFocused = -1;
return 1;
}