Moved the register to MS function to a variable, added Giants enums, implemented plugin system
This commit is contained in:
parent
3fd1ea47b3
commit
d594e38be5
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
maps/*.gck
|
@ -30,9 +30,10 @@ class Netserver:
|
|||||||
gameserverthread = threading.Thread(target=self.handle_packets)
|
gameserverthread = threading.Thread(target=self.handle_packets)
|
||||||
gameserverthread.start()
|
gameserverthread.start()
|
||||||
|
|
||||||
#ms = MasterServer(self.server)
|
if self.server.register_with_ms:
|
||||||
#statsserverthread = threading.Thread(target=ms.register_and_run)
|
ms = MasterServer(self.server)
|
||||||
#statsserverthread.start()
|
ms.register()
|
||||||
|
|
||||||
|
|
||||||
gameserverthread.join()
|
gameserverthread.join()
|
||||||
#statsserverthread.join()
|
#statsserverthread.join()
|
||||||
@ -74,7 +75,7 @@ class Netserver:
|
|||||||
er.ApplicationInstanceGUID = self.guid
|
er.ApplicationInstanceGUID = self.guid
|
||||||
er.ApplicationGUID = eq.ApplicationGUID
|
er.ApplicationGUID = eq.ApplicationGUID
|
||||||
er.ApplicationReservedData = b'\xff' # Map ID
|
er.ApplicationReservedData = b'\xff' # Map ID
|
||||||
er.ApplicationReservedData += b'\x00\x04\x00'
|
er.ApplicationReservedData += b'\x00\x04\x00' # game type and teams
|
||||||
er.ApplicationReservedData += b'\xd9\x05' # game version
|
er.ApplicationReservedData += b'\xd9\x05' # game version
|
||||||
er.ApplicationReservedData += b'\x02\x92\x05\x00\x01\x00\x00\x00\x00\x00' # Unknown
|
er.ApplicationReservedData += b'\x02\x92\x05\x00\x01\x00\x00\x00\x00\x00' # Unknown
|
||||||
er.ApplicationReservedData += b'\x9c\x53\xf4\xde' # Seems to be a checksum of current map
|
er.ApplicationReservedData += b'\x9c\x53\xf4\xde' # Seems to be a checksum of current map
|
||||||
|
@ -0,0 +1,25 @@
|
|||||||
|
class Teams:
|
||||||
|
MvM = 0x00
|
||||||
|
MvMvM = 0x01
|
||||||
|
RvR = 0x02
|
||||||
|
MvR = 0x03
|
||||||
|
MvRvK = 0x04
|
||||||
|
MvK = 0x05
|
||||||
|
RvK = 0x06
|
||||||
|
TeamB = 0x07
|
||||||
|
Crash = 0x5a
|
||||||
|
|
||||||
|
|
||||||
|
class GameTypes:
|
||||||
|
TeamDeathmatch = 0x00
|
||||||
|
TeamDeathmatchWithFullBase = 0x01
|
||||||
|
CaptureSmartie = 0x02
|
||||||
|
CaptureSmartieWithFullBase = 0x03
|
||||||
|
BaseBuildDeathmatch = 0x04
|
||||||
|
BaseBuildCaptureSmartie = 0x05
|
||||||
|
DefendBase = 0x06
|
||||||
|
DefendBaseCaptureSmartie = 0x07
|
||||||
|
GTypeStone = 0x08
|
||||||
|
GTypeWood = 0x09
|
||||||
|
Crash = 0x0a
|
||||||
|
GTypeNull = 0x0c
|
@ -1,11 +1,24 @@
|
|||||||
class Map:
|
import os
|
||||||
def __init__(self, mapname="Unknown mapname"):
|
|
||||||
self.mapname = mapname
|
|
||||||
self.checksum = None
|
|
||||||
|
|
||||||
def load_map(self, mapname):
|
|
||||||
self.checksum = Map.checksum(mapname)
|
class Map:
|
||||||
|
def __init__(self, mappath):
|
||||||
|
self.mappath = mappath
|
||||||
|
self.checksum = None
|
||||||
|
self.mapname = "Unknown map"
|
||||||
|
self.load_map(mappath)
|
||||||
|
|
||||||
|
def load_map(self, mappath):
|
||||||
|
if not os.path.exists("maps/"+mappath):
|
||||||
|
raise Exception("Map not found: "+mappath)
|
||||||
|
|
||||||
|
if not mappath.endswith(".gck"):
|
||||||
|
raise Exception("Server only supports GCK maps")
|
||||||
|
|
||||||
|
self.mapname = mappath.split(".gck")[0]
|
||||||
|
self.checksum = Map.checksum(mappath)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def checksum(mapname):
|
def checksum(mapname):
|
||||||
|
# TODO
|
||||||
return 1
|
return 1
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import socket
|
import socket
|
||||||
from dpnet.packet import Packet
|
from dpnet.packet import Packet
|
||||||
|
import threading
|
||||||
|
|
||||||
|
|
||||||
class MasterServer:
|
class MasterServer:
|
||||||
@ -9,22 +10,27 @@ class MasterServer:
|
|||||||
self.masterserverip = "gckms.no-ip.org"
|
self.masterserverip = "gckms.no-ip.org"
|
||||||
self.masterserverport = 27900
|
self.masterserverport = 27900
|
||||||
|
|
||||||
|
def register(self):
|
||||||
|
statsserverthread = threading.Thread(target=self.register_and_run)
|
||||||
|
statsserverthread.start()
|
||||||
|
statsserverthread.join()
|
||||||
|
|
||||||
def register_and_run(self):
|
def register_and_run(self):
|
||||||
self.socket.bind((self.server.listen_ip, 8911))
|
self.socket.bind((self.server.listen_ip, 8911))
|
||||||
print("Listening to " + self.server.listen_ip + ":" + str(8911))
|
print("Listening to " + self.server.listen_ip + ":" + str(8911))
|
||||||
print("Registering to Master Server")
|
print("Registering to Master Server")
|
||||||
self.register()
|
self._register()
|
||||||
self.keepalive()
|
self.keepalive()
|
||||||
self.handle_packets()
|
self.handle_packets()
|
||||||
|
|
||||||
def register(self):
|
def _register(self):
|
||||||
packet = Packet()
|
packet = Packet()
|
||||||
packet.write("019711".encode("ascii"))
|
packet.write(("0"+str(self.server.listen_port)).encode("ascii"))
|
||||||
self.socket.sendto(packet.getvalue(), (self.masterserverip, self.masterserverport))
|
self.socket.sendto(packet.getvalue(), (self.masterserverip, self.masterserverport))
|
||||||
|
|
||||||
def keepalive(self):
|
def keepalive(self):
|
||||||
packet = Packet()
|
packet = Packet()
|
||||||
packet.write("119711".encode("ascii"))
|
packet.write(("1"+str(self.server.listen_port)).encode("ascii"))
|
||||||
self.socket.sendto(packet.getvalue(), (self.masterserverip, self.masterserverport))
|
self.socket.sendto(packet.getvalue(), (self.masterserverip, self.masterserverport))
|
||||||
|
|
||||||
def handle_packets(self):
|
def handle_packets(self):
|
||||||
|
0
plugins/__init__.py
Normal file
0
plugins/__init__.py
Normal file
14
plugins/greetings.py
Normal file
14
plugins/greetings.py
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
class Greetings:
|
||||||
|
def __init__(self, server):
|
||||||
|
self.server = server
|
||||||
|
|
||||||
|
def on_player_join(self, player):
|
||||||
|
self.server.broadcast_message("Welcome "+player.name+"!")
|
||||||
|
|
||||||
|
def on_map_change(self, newmap):
|
||||||
|
self.server.broadcast_message("You are now playing on "+newmap.mapname)
|
||||||
|
|
||||||
|
|
||||||
|
def setup(server):
|
||||||
|
plugin = Greetings(server)
|
||||||
|
server.add_plugin(plugin)
|
86
server.py
86
server.py
@ -2,8 +2,14 @@ from giants.map import Map
|
|||||||
from giants.player import Player
|
from giants.player import Player
|
||||||
from dpnet.netserver import Netserver
|
from dpnet.netserver import Netserver
|
||||||
from dpnet.session import Session
|
from dpnet.session import Session
|
||||||
from dpnet.DFrame import DFrame
|
|
||||||
import socket
|
import socket
|
||||||
|
import importlib
|
||||||
|
import os
|
||||||
|
from giants import Teams, GameTypes
|
||||||
|
from utils.logger import setup_logger
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
logger = setup_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class Server:
|
class Server:
|
||||||
@ -14,51 +20,69 @@ class Server:
|
|||||||
fake_session.ip = "127.0.0.1"
|
fake_session.ip = "127.0.0.1"
|
||||||
fake_session.port = 3333
|
fake_session.port = 3333
|
||||||
self.players = [Player("Amazed4", fake_session)]
|
self.players = [Player("Amazed4", fake_session)]
|
||||||
self.currentmap = kwargs.get("map", Map("wow rly"))
|
self.currentmap = kwargs.get("map", Map("Three Way Island - Canyons.gck"))
|
||||||
self.maxplayers = kwargs.get("maxplayers", 20)
|
self.maxplayers = kwargs.get("maxplayers", 20)
|
||||||
self.name = kwargs.get("name", "Default Server Name")
|
self.name = kwargs.get("name", "Default Server Name")
|
||||||
self.accept_new_players = True
|
self.accept_new_players = True
|
||||||
self.register_with_ms = False
|
self.register_with_ms = kwargs.get("register", False)
|
||||||
|
self.teams = kwargs.get("teams", Teams.MvM)
|
||||||
|
self.game_type = kwargs.get("gametype", GameTypes.TeamDeathmatchWithFullBase)
|
||||||
|
self._plugins = []
|
||||||
|
|
||||||
# events
|
def add_player(self, player):
|
||||||
self._on_new_player = []
|
|
||||||
self._on_new_map = []
|
|
||||||
|
|
||||||
def new_player(self, player):
|
|
||||||
self.players.append(player)
|
self.players.append(player)
|
||||||
for func in self._on_new_player:
|
self._broadcast_event("on_player_join", player)
|
||||||
func(player)
|
|
||||||
|
|
||||||
def change_map(self, mapname):
|
def add_plugin(self, plugin):
|
||||||
for func in self._on_new_map:
|
self._plugins.append(plugin)
|
||||||
func(mapname)
|
|
||||||
|
|
||||||
def on_new_player(self, func):
|
def change_map(self, mappath):
|
||||||
self._on_new_player.append(func)
|
try:
|
||||||
return func
|
self.currentmap = Map(mappath)
|
||||||
|
self._broadcast_event("on_map_change", self.currentmap)
|
||||||
|
except Exception:
|
||||||
|
logger.error("Could not change map")
|
||||||
|
|
||||||
|
def _broadcast_event(self, event, *args):
|
||||||
|
logger.debug("Broadcasting event "+event)
|
||||||
|
for plugin in self._plugins:
|
||||||
|
if hasattr(plugin, event):
|
||||||
|
func = getattr(plugin, event)
|
||||||
|
if callable(func):
|
||||||
|
try:
|
||||||
|
func(args)
|
||||||
|
except Exception:
|
||||||
|
logger.error("Could not call plugin function: "+plugin.__name__+"."+event)
|
||||||
|
traceback.print_exc()
|
||||||
|
|
||||||
|
def load_plugins(self):
|
||||||
|
plugins = os.listdir("plugins")
|
||||||
|
for plugin in plugins:
|
||||||
|
if os.path.isdir("plugins/"+plugin) or plugin == "__init__.py":
|
||||||
|
continue
|
||||||
|
if not plugin.endswith(".py"):
|
||||||
|
continue
|
||||||
|
pluginname = plugin.split(".py")[0]
|
||||||
|
try:
|
||||||
|
module = importlib.import_module("plugins."+pluginname)
|
||||||
|
if hasattr(module, "setup"):
|
||||||
|
setup = getattr(module, "setup")
|
||||||
|
if callable(setup):
|
||||||
|
logger.info("Loading plugin "+module.__name__)
|
||||||
|
module.setup(self)
|
||||||
|
except Exception:
|
||||||
|
logger.warn("Could not load plugin "+plugin)
|
||||||
|
traceback.print_exc()
|
||||||
|
|
||||||
def broadcast_message(self, text):
|
def broadcast_message(self, text):
|
||||||
for player in self.players:
|
for player in self.players:
|
||||||
player.session.send_gamedata(b'\x35\x80\x81'+text.encode("ascii")+b'\x00\x00')
|
player.session.send_gamedata(b'\x35\x80\x81'+text.encode("ascii")+b'\x00\x00')
|
||||||
|
|
||||||
def on_new_map(self, func):
|
|
||||||
self._on_new_map.append(func)
|
|
||||||
return func
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
|
self.load_plugins()
|
||||||
return Netserver(self).run()
|
return Netserver(self).run()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
server = Server(name="giantsd", map=Map("expect crashes"), maxplayers=10)
|
server = Server(name="giantsd", maxplayers=10, register=False)
|
||||||
|
|
||||||
@server.on_new_player
|
|
||||||
def new_player(player):
|
|
||||||
#print("A NEW PLAYER HAS JOINED: %s" % player)
|
|
||||||
pass
|
|
||||||
|
|
||||||
@server.on_new_map
|
|
||||||
def new_map(mapname):
|
|
||||||
pass
|
|
||||||
|
|
||||||
server.run() # blocking
|
server.run() # blocking
|
Loading…
Reference in New Issue
Block a user