forked from hipstercat/giantsd
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.start()
|
||||
|
||||
#ms = MasterServer(self.server)
|
||||
#statsserverthread = threading.Thread(target=ms.register_and_run)
|
||||
#statsserverthread.start()
|
||||
if self.server.register_with_ms:
|
||||
ms = MasterServer(self.server)
|
||||
ms.register()
|
||||
|
||||
|
||||
gameserverthread.join()
|
||||
#statsserverthread.join()
|
||||
@ -74,7 +75,7 @@ class Netserver:
|
||||
er.ApplicationInstanceGUID = self.guid
|
||||
er.ApplicationGUID = eq.ApplicationGUID
|
||||
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'\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
|
||||
|
@ -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:
|
||||
def __init__(self, mapname="Unknown mapname"):
|
||||
self.mapname = mapname
|
||||
self.checksum = None
|
||||
import os
|
||||
|
||||
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
|
||||
def checksum(mapname):
|
||||
# TODO
|
||||
return 1
|
||||
|
@ -1,5 +1,6 @@
|
||||
import socket
|
||||
from dpnet.packet import Packet
|
||||
import threading
|
||||
|
||||
|
||||
class MasterServer:
|
||||
@ -9,22 +10,27 @@ class MasterServer:
|
||||
self.masterserverip = "gckms.no-ip.org"
|
||||
self.masterserverport = 27900
|
||||
|
||||
def register(self):
|
||||
statsserverthread = threading.Thread(target=self.register_and_run)
|
||||
statsserverthread.start()
|
||||
statsserverthread.join()
|
||||
|
||||
def register_and_run(self):
|
||||
self.socket.bind((self.server.listen_ip, 8911))
|
||||
print("Listening to " + self.server.listen_ip + ":" + str(8911))
|
||||
print("Registering to Master Server")
|
||||
self.register()
|
||||
self._register()
|
||||
self.keepalive()
|
||||
self.handle_packets()
|
||||
|
||||
def register(self):
|
||||
def _register(self):
|
||||
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))
|
||||
|
||||
def keepalive(self):
|
||||
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))
|
||||
|
||||
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 dpnet.netserver import Netserver
|
||||
from dpnet.session import Session
|
||||
from dpnet.DFrame import DFrame
|
||||
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:
|
||||
@ -14,51 +20,69 @@ class Server:
|
||||
fake_session.ip = "127.0.0.1"
|
||||
fake_session.port = 3333
|
||||
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.name = kwargs.get("name", "Default Server Name")
|
||||
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
|
||||
self._on_new_player = []
|
||||
self._on_new_map = []
|
||||
|
||||
def new_player(self, player):
|
||||
def add_player(self, player):
|
||||
self.players.append(player)
|
||||
for func in self._on_new_player:
|
||||
func(player)
|
||||
self._broadcast_event("on_player_join", player)
|
||||
|
||||
def change_map(self, mapname):
|
||||
for func in self._on_new_map:
|
||||
func(mapname)
|
||||
def add_plugin(self, plugin):
|
||||
self._plugins.append(plugin)
|
||||
|
||||
def on_new_player(self, func):
|
||||
self._on_new_player.append(func)
|
||||
return func
|
||||
def change_map(self, mappath):
|
||||
try:
|
||||
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):
|
||||
for player in self.players:
|
||||
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):
|
||||
self.load_plugins()
|
||||
return Netserver(self).run()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
server = Server(name="giantsd", map=Map("expect crashes"), maxplayers=10)
|
||||
|
||||
@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 = Server(name="giantsd", maxplayers=10, register=False)
|
||||
server.run() # blocking
|
Loading…
Reference in New Issue
Block a user