Move sorting into save operation
This commit is contained in:
79
server.py
79
server.py
@@ -528,6 +528,39 @@ class Server:
|
|||||||
return round(self.totalClients / self.updateCount)
|
return round(self.totalClients / self.updateCount)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
# calculate score for server list ranking (higher values first)
|
||||||
|
def get_score(self):
|
||||||
|
points = 0
|
||||||
|
meta = self.meta
|
||||||
|
|
||||||
|
# 1 per client
|
||||||
|
points += meta["clients"]
|
||||||
|
|
||||||
|
# Penalize highly loaded servers to improve player distribution
|
||||||
|
cap = int(meta["clients_max"] * 0.80)
|
||||||
|
if meta["clients"] > cap:
|
||||||
|
points -= meta["clients"] - cap
|
||||||
|
|
||||||
|
# 1 per month of age, limited to 8
|
||||||
|
points += min(8, meta["game_time"] / (60*60*24*30))
|
||||||
|
|
||||||
|
# 1/2 per average client, limited to 4
|
||||||
|
points += min(4, self.get_average_clients() / 2)
|
||||||
|
|
||||||
|
# -8 for unrealistic max_clients
|
||||||
|
if meta["clients_max"] > 200:
|
||||||
|
points -= 8
|
||||||
|
|
||||||
|
# -8 per second of ping over 0.4s
|
||||||
|
if meta["ping"] > 0.4:
|
||||||
|
points -= (meta["ping"] - 0.4) * 8
|
||||||
|
|
||||||
|
# reduction to 60% for servers that support both legacy (v4) and v5 clients
|
||||||
|
if meta["proto_min"] <= 32 and meta["proto_max"] > 36:
|
||||||
|
points *= 0.6
|
||||||
|
|
||||||
|
return points
|
||||||
|
|
||||||
def track_update(self, old: 'Server', is_update: bool):
|
def track_update(self, old: 'Server', is_update: bool):
|
||||||
# this might look a bit strange, but once a `Server` object is put into
|
# this might look a bit strange, but once a `Server` object is put into
|
||||||
# list it becomes immutable since it's under lock. So we have to copy
|
# list it becomes immutable since it's under lock. So we have to copy
|
||||||
@@ -575,6 +608,7 @@ class ServerList:
|
|||||||
self.storagePath = os.path.join(app.root_path, "store.json")
|
self.storagePath = os.path.join(app.root_path, "store.json")
|
||||||
self.publicPath = os.path.join(app.static_folder, "list.json")
|
self.publicPath = os.path.join(app.static_folder, "list.json")
|
||||||
self.lock = RLock()
|
self.lock = RLock()
|
||||||
|
|
||||||
self.load()
|
self.load()
|
||||||
self.purgeOld()
|
self.purgeOld()
|
||||||
|
|
||||||
@@ -605,42 +639,6 @@ class ServerList:
|
|||||||
self.save()
|
self.save()
|
||||||
self.savePublic()
|
self.savePublic()
|
||||||
|
|
||||||
def sort(self):
|
|
||||||
def server_points(server: Server):
|
|
||||||
points = 0
|
|
||||||
meta = server.meta
|
|
||||||
|
|
||||||
# 1 per client
|
|
||||||
points += meta["clients"]
|
|
||||||
|
|
||||||
# Penalize highly loaded servers to improve player distribution.
|
|
||||||
cap = int(meta["clients_max"] * 0.80)
|
|
||||||
if meta["clients"] > cap:
|
|
||||||
points -= meta["clients"] - cap
|
|
||||||
|
|
||||||
# 1 per month of age, limited to 8
|
|
||||||
points += min(8, meta["game_time"] / (60*60*24*30))
|
|
||||||
|
|
||||||
# 1/2 per average client, limited to 4
|
|
||||||
points += min(4, server.get_average_clients() / 2)
|
|
||||||
|
|
||||||
# -8 for unrealistic max_clients
|
|
||||||
if meta["clients_max"] > 200:
|
|
||||||
points -= 8
|
|
||||||
|
|
||||||
# -8 per second of ping over 0.4s
|
|
||||||
if meta["ping"] > 0.4:
|
|
||||||
points -= (meta["ping"] - 0.4) * 8
|
|
||||||
|
|
||||||
# reduction to 60% for servers that support both legacy (v4) and v5 clients
|
|
||||||
if meta["proto_min"] <= 32 and meta["proto_max"] > 36:
|
|
||||||
points *= 0.6
|
|
||||||
|
|
||||||
return points
|
|
||||||
|
|
||||||
with self.lock:
|
|
||||||
self.list.sort(key=server_points, reverse=True)
|
|
||||||
|
|
||||||
def purgeOld(self):
|
def purgeOld(self):
|
||||||
cutoff = int(time.time()) - app.config["PURGE_TIME"]
|
cutoff = int(time.time()) - app.config["PURGE_TIME"]
|
||||||
with self.lock:
|
with self.lock:
|
||||||
@@ -677,10 +675,14 @@ class ServerList:
|
|||||||
|
|
||||||
def savePublic(self):
|
def savePublic(self):
|
||||||
with self.lock:
|
with self.lock:
|
||||||
|
# sort, but don't modify internal list
|
||||||
|
sorted_list = sorted(self.list,
|
||||||
|
key=(lambda server: server.get_score()), reverse=True)
|
||||||
|
|
||||||
out_list = []
|
out_list = []
|
||||||
servers = len(self.list)
|
servers = len(sorted_list)
|
||||||
clients = 0
|
clients = 0
|
||||||
for server in self.list:
|
for server in sorted_list:
|
||||||
out_list.append(server.to_list_json())
|
out_list.append(server.to_list_json())
|
||||||
clients += server.meta["clients"]
|
clients += server.meta["clients"]
|
||||||
|
|
||||||
@@ -701,7 +703,6 @@ class ServerList:
|
|||||||
else:
|
else:
|
||||||
self.list.append(server)
|
self.list.append(server)
|
||||||
|
|
||||||
self.sort()
|
|
||||||
self.save()
|
self.save()
|
||||||
self.savePublic()
|
self.savePublic()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user