mirror of
https://github.com/barronwaffles/dwc_network_server_emulator.git
synced 2026-08-24 19:45:38 -05:00
Preliminary matchmaking
I don't know how well it works yet until more testing is done, but matchmaking works now.
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
|
||||
from multiprocessing.managers import BaseManager
|
||||
from multiprocessing import freeze_support
|
||||
import other.utils as utils
|
||||
|
||||
server_list = {}
|
||||
|
||||
@@ -264,7 +265,7 @@ def update_server_list(gameid, session, value):
|
||||
|
||||
# Add new server
|
||||
value['__session__'] = session
|
||||
print "Added %s to the server list for %s" % (gameid, value)
|
||||
utils.print_log("Added %s to the server list for %s" % (value, gameid))
|
||||
server_list[gameid].append(value)
|
||||
|
||||
def delete_server(gameid, session):
|
||||
@@ -283,9 +284,6 @@ def start_server():
|
||||
address = ("127.0.0.1", 27500)
|
||||
password = ""
|
||||
|
||||
#server_list["tetrisds"] = []
|
||||
#server_list["tetrisds"].append({'__session__': 0, 'key': "helloworld", 'value': "Hello, world!", 'extra': "Test"})
|
||||
|
||||
GamespyServerDatabase.register("get_server_list", callable=lambda:server_list)
|
||||
GamespyServerDatabase.register("find_servers", callable=find_servers)
|
||||
GamespyServerDatabase.register("update_server_list", callable=update_server_list)
|
||||
|
||||
@@ -198,6 +198,12 @@ while 1:
|
||||
if "statechanged" in k:
|
||||
if k['statechanged'] == "1": # Create server
|
||||
if k['publicport'] != "0" and k['publicip'] != "0" and k['maxplayers'] != "0":
|
||||
# dwc_mtype controls what kind of server query we're looking for.
|
||||
# dwc_mtype = 0 is used when looking for a matchmaking game.
|
||||
# dwc_mtype = 1 is unknown.
|
||||
# dwc_mtype = 2 is used when hosting a friends only game (possibly other uses too).
|
||||
# dwc_mtype = 3 is used when looking for a friends only game (possibly other uses too).
|
||||
|
||||
# Some memory could be saved by clearing out any unwanted fields from k before sending.
|
||||
server_manager.update_server_list(k['gamename'] , session_id, k)
|
||||
elif k['statechanged'] == "2": # Close server
|
||||
|
||||
@@ -8,6 +8,8 @@ from twisted.internet import reactor
|
||||
|
||||
import socket
|
||||
import ctypes
|
||||
import time
|
||||
from threading import Thread
|
||||
|
||||
import gamespy.gs_utility as gs_utils
|
||||
import other.utils as utils
|
||||
@@ -101,6 +103,12 @@ class Session(LineReceiver):
|
||||
self.addr = addr
|
||||
self.forward_to_client = False
|
||||
self.forward_client = ()
|
||||
self.is_searching = False
|
||||
|
||||
# Amount of time (in seconds) we can search for a match before getting kicked off.
|
||||
# Set to -1 to allow keep searching forever until a server appears.
|
||||
#self.timeout = 60 * 10
|
||||
self.timeout = -1
|
||||
|
||||
def rawDataReceived(self, data):
|
||||
# First 2 bytes are the packet size.
|
||||
@@ -191,23 +199,16 @@ class Session(LineReceiver):
|
||||
#print "%08x" % options
|
||||
#print "%d %08x" % (max_servers, source_ip)
|
||||
|
||||
# Get dictionary from master server list server.
|
||||
self.server_list = get_server_list(query_game, filter, fields, max_servers)._getvalue()
|
||||
if self.is_searching == False:
|
||||
self.is_searching = True
|
||||
|
||||
# Generate encrypted server list and send to client.
|
||||
print self.server_list
|
||||
for server in self.server_list:
|
||||
# Generate binary server list data
|
||||
data = generate_server_list_data(self.addr, fields, server)
|
||||
# I still want the connection to close properly when the client disconnects, so put the server search
|
||||
# part into its own thread.
|
||||
# The game will create a new connection for every search query, so don't worry about setting
|
||||
# self.is_searching to False.
|
||||
t = Thread(target = self.find_server, args=(query_game, filter, fields, max_servers, game_name, challenge))
|
||||
t.start()
|
||||
|
||||
# Encrypt data
|
||||
enc = gs_utils.EncTypeX()
|
||||
data = enc.encrypt(secret_key_list[game_name], challenge, data)
|
||||
|
||||
# Send to client
|
||||
self.transport.write(bytes(data))
|
||||
utils.print_log("Sent server list message to %s:%s..." % (self.addr.host, self.addr.port))
|
||||
break
|
||||
|
||||
|
||||
elif data[2] == '\x02': # Send message request
|
||||
@@ -226,6 +227,37 @@ class Session(LineReceiver):
|
||||
else:
|
||||
utils.print_log("Received unknown command (%02x) from %s:%s... %s" % (ord(data[2]), self.addr.host, self.addr.port, data))
|
||||
|
||||
def find_server(self, query_game, filter, fields, max_servers, game_name, challenge):
|
||||
# Get dictionary from master server list server.
|
||||
# The game sends a search query only once so we must loop until something is found.
|
||||
# Search for the specified amount of time, or if self.timeout is set to -1, until a match is found.
|
||||
start = time.time()
|
||||
while True:
|
||||
self.server_list = get_server_list(query_game, filter, fields, max_servers)._getvalue()
|
||||
|
||||
if self.server_list != []:
|
||||
break
|
||||
|
||||
time.sleep(5) # Sleep 1 second
|
||||
|
||||
if self.timeout != -1 and time.time() - start > self.timeout:
|
||||
break
|
||||
|
||||
# Generate encrypted server list and send to client.
|
||||
print self.server_list
|
||||
for server in self.server_list:
|
||||
# Generate binary server list data
|
||||
data = generate_server_list_data(self.addr, fields, server)
|
||||
|
||||
# Encrypt data
|
||||
enc = gs_utils.EncTypeX()
|
||||
data = enc.encrypt(secret_key_list[game_name], challenge, data)
|
||||
|
||||
# Send to client
|
||||
self.transport.write(bytes(data))
|
||||
utils.print_log("Sent server list message to %s:%s..." % (self.addr.host, self.addr.port))
|
||||
break
|
||||
|
||||
|
||||
class SessionFactory(Factory):
|
||||
def __init__(self):
|
||||
|
||||
Reference in New Issue
Block a user