giantsd/server.py

166 lines
6.3 KiB
Python
Raw Normal View History

2019-01-22 01:30:42 +01:00
from giants.map import Map
from giants.player import Player
from dpnet.netserver import Netserver
from dpnet.session import Session
import socket
import importlib
import os
2019-02-19 01:01:31 +01:00
from giants import Teams, GameTypes, ChatColor, ChatType
from utils.logger import setup_logger
import traceback
import asyncio
2019-02-19 01:01:31 +01:00
from aioconsole import ainput
2019-03-05 01:30:20 +01:00
import struct
logger = setup_logger(__name__)
2019-01-22 01:30:42 +01:00
class Server:
def __init__(self, **kwargs):
self.listen_ip = kwargs.get("ip", "0.0.0.0")
self.listen_port = kwargs.get("port", 19711)
2019-02-05 01:35:22 +01:00
self.register_with_ms = kwargs.get("register", False)
self.teams = kwargs.get("teams", Teams.MvM)
self.game_type = kwargs.get("gametype", GameTypes.TeamDeathmatchWithFullBase)
2019-03-05 01:49:13 +01:00
self.currentmap = kwargs.get("map", Map("Testmap.gck"))
2019-01-22 01:30:42 +01:00
self.maxplayers = kwargs.get("maxplayers", 20)
self.name = kwargs.get("name", "Default Server Name")
2019-02-05 01:35:22 +01:00
fake_session = Session(socket.socket(socket.AF_INET, socket.SOCK_DGRAM))
fake_session.ip = "127.0.0.1"
fake_session.port = 3333
self.players = [Player("[Server]", fake_session)]
2019-02-19 01:01:31 +01:00
fake_player = Session(socket.socket(socket.AF_INET, socket.SOCK_DGRAM))
fake_player.ip = "127.0.0.1"
fake_player.port = 3334
self.players.append(Player("Bot 1", fake_player))
2019-02-28 04:01:03 +01:00
fake_player = Session(socket.socket(socket.AF_INET, socket.SOCK_DGRAM))
fake_player.ip = "127.0.0.1"
fake_player.port = 3334
self.players.append(Player("Bot 2", fake_player))
fake_player = Session(socket.socket(socket.AF_INET, socket.SOCK_DGRAM))
fake_player.ip = "127.0.0.1"
fake_player.port = 3334
self.players.append(Player("Bot 3", fake_player))
2019-01-22 01:30:42 +01:00
self.accept_new_players = True
2019-01-23 10:54:51 +01:00
self.version = 1.497
2019-02-05 22:33:25 +01:00
self.points_per_kill = 1
2019-01-23 10:54:51 +01:00
self.points_per_capture = 5
self.detente_time = 0 # minutes
self._plugins = []
2019-02-05 01:35:22 +01:00
self.tempplayers = []
self.running = True
self.ticks = 60
def update(self):
#logger.debug("Calling update")
pass
2019-01-22 01:30:42 +01:00
async def add_player(self, player):
2019-02-05 01:35:22 +01:00
self.tempplayers.remove(player)
2019-01-22 01:30:42 +01:00
self.players.append(player)
2019-02-19 01:01:31 +01:00
await self.broadcast_event("on_player_join", player)
2019-02-05 01:35:22 +01:00
# todo: remove
def create_temp_player(self, player):
self.tempplayers.append(player)
async def remove_player(self, player):
2019-02-05 01:35:22 +01:00
self.players.remove(player)
2019-02-19 01:01:31 +01:00
await self.broadcast_event("on_player_left", player)
2019-02-05 01:35:22 +01:00
def add_plugin(self, plugin):
self._plugins.append(plugin)
async def change_map(self, mappath):
try:
self.currentmap = Map(mappath)
2019-02-19 01:01:31 +01:00
await self.broadcast_event("on_map_change", self.currentmap)
except Exception:
logger.error("Could not change map")
2019-01-22 01:30:42 +01:00
2019-02-19 01:01:31 +01:00
async 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:
await func(*args)
except Exception:
2019-02-05 01:35:22 +01:00
logger.error("Could not call plugin function: "+plugin.__class__.__name__+"."+event)
traceback.print_exc()
2019-01-22 01:30:42 +01:00
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.warning("Could not load plugin "+plugin)
traceback.print_exc()
2019-01-22 01:30:42 +01:00
2019-02-19 01:01:31 +01:00
async def broadcast_message(self, text, color=ChatColor.Orange, type=ChatType.All):
2019-01-22 01:30:42 +01:00
for player in self.players:
if player.name == "[Server]":
continue
2019-02-19 01:01:31 +01:00
await player.send_message(text, color=color, type=type)
async def ask_command(self):
while True:
try:
cmd = await ainput(">")
logger.debug("Sending game payload %s", cmd)
for player in self.players:
if player.name == "[Server]":
continue
await player.session.send_gamedata(bytes.fromhex(cmd), acknow=False)
except:
traceback.print_exc()
2019-02-28 04:01:03 +01:00
async def broadcast_gamedata(self, payload, **kwargs):
for player in self.players:
if player.name == "[Server]":
continue
await player.session.send_gamedata(payload, **kwargs)
2019-03-05 01:30:20 +01:00
async def broadcast_message_except(self, player, text, color=ChatColor.Yellow, type=ChatType.All):
for pplayer in self.players:
if pplayer.name == "[Server]" or pplayer == player:
continue
await pplayer.send_message(text, color=color, type=type)
async def spawn(self, objid, plix, model):
await self.broadcast_gamedata(bytes.fromhex("05" + plix + struct.pack("<B", objid).hex() + "0000" + model + "00000000"), acknow=False)
await self.broadcast_gamedata(bytes.fromhex("0a32000000" + plix + struct.pack("<B", objid).hex() + "000001" + model + "000000ff00000000000000000000000000000000000000000000000000000000000000000000000a12000000" + plix + struct.pack("<B", objid).hex() + "0000" + model + "020000000000000000"), acknow=False)
2019-01-22 01:30:42 +01:00
if __name__ == '__main__':
2019-02-28 04:01:03 +01:00
server = Server(name="giantsd", maxplayers=20, register=False, teams=Teams.MvM) #, map=Map("Three Way Island - Canyons.gck"))
server.load_plugins()
loop = asyncio.get_event_loop()
listen = loop.create_datagram_endpoint(lambda: Netserver(server), local_addr=(server.listen_ip, server.listen_port))
transport, protocol = loop.run_until_complete(listen)
2019-02-19 01:01:31 +01:00
loop.create_task(server.ask_command())
try:
loop.run_forever()
except KeyboardInterrupt:
pass
transport.close()
loop.close()