Added debug command, WIP sync joining and leaving

This commit is contained in:
Amazed 2019-03-07 02:09:50 +01:00
parent d946f792cd
commit 1589188357
5 changed files with 64 additions and 34 deletions

View File

@ -173,7 +173,7 @@ class Netserver(asyncio.DatagramProtocol):
return return
else: else:
logger.debug("New connection. Sending a CFRAME CONNECTED.") logger.debug("New connection. Sending a CFRAME CONNECTED.")
session = Session(self.remotesocket) session = Session(self.server, self.remotesocket)
session.SessID = cframe.SessID session.SessID = cframe.SessID
session.ip = addr[0] session.ip = addr[0]
session.port = addr[1] session.port = addr[1]
@ -262,7 +262,7 @@ class Netserver(asyncio.DatagramProtocol):
logger.debug("%s:%s > %s (END_STREAM)", addr[0], addr[1], data.getvalue().hex()) logger.debug("%s:%s > %s (END_STREAM)", addr[0], addr[1], data.getvalue().hex())
if not session: if not session:
logger.error("Received a END STREAM packet for a non fully connected session") logger.error("Received a END STREAM packet for a non fully connected session")
session = Session(self.remotesocket) session = Session(self.server, self.remotesocket)
session.ip = addr[0] session.ip = addr[0]
session.port = addr[1] session.port = addr[1]
session.SessID = dframe.SessID session.SessID = dframe.SessID
@ -377,25 +377,12 @@ class Netserver(asyncio.DatagramProtocol):
await self.server.add_player(player) await self.server.add_player(player)
await player.session.send_gamedata(b'\x3c'+struct.pack("<L", player.id)+b"\x00", acknow=True) await player.session.send_gamedata(b'\x3c'+struct.pack("<L", player.id)+b"\x00", acknow=True)
p1 = b'\x01' + struct.pack("<B", len(self.server.players)) await player.session.send_gamedata(self.build_players_dpid(player))
for pplayer in self.server.players: await self.server.broadcast_gamedata_except(player, self.build_players_dpid())
p1 += struct.pack("<L", pplayer.id)
for pplayer in self.server.players:
if pplayer.name == "[Server]":
continue
p1 += b'\x0e'
p1 += b"\x01\x00"
for pplayer in self.server.players:
if pplayer == player or pplayer.name == "[Server]":
continue
p1 += struct.pack("<B", pplayer.team)
p1 += b'\x00\x00'
await player.session.send_gamedata(p1, acknow=False)
#await player.session.send_gamedata(b'\x3d\x00\x5b\x53\x65\x72\x76\x65\x72\x5d'+b"\x00"*25, acknow=True) # [SERVER]
plid=0 plid=0
for pplayer in self.server.players: for pplayer in self.server.players:
await player.session.send_gamedata(b'\x3d'+struct.pack("<B", plid)+pplayer.name.encode("ascii")+b"\x00"*(33-len(pplayer.name.encode("ascii"))), acknow=True) # playername await self.server.broadcast_gamedata(b'\x3d'+struct.pack("<B", plid)+pplayer.name.encode("ascii")+b"\x00"*(33-len(pplayer.name.encode("ascii")))) # playername
plid+=1 plid+=1
elif payload[0] == 0x0f: elif payload[0] == 0x0f:
player = self.get_player(session) player = self.get_player(session)
@ -427,8 +414,11 @@ class Netserver(asyncio.DatagramProtocol):
playerid = p.getULong() playerid = p.getULong()
unknown = p.getByte() unknown = p.getByte()
await player.change_team(team % 128) if player.team > 3 >= team % 128:
await self.server.broadcast_event("on_player_change_team", player, player.team) # ignore
logger.info("%s tried to change team to %s but failed" % (player.name, team))
else:
await player.change_team(team % 128)
elif payload[0] == 0x35: # CMSG_SEND_CHAT_MESSAGE: messagetype? (byte), team? (byte), message (string) elif payload[0] == 0x35: # CMSG_SEND_CHAT_MESSAGE: messagetype? (byte), team? (byte), message (string)
player = self.get_player(session) player = self.get_player(session)
if not player: if not player:
@ -558,7 +548,8 @@ class Netserver(asyncio.DatagramProtocol):
player.o = orientation player.o = orientation
#logger.info("%s is now at coords (%s,%s,%s)", player.name, player.x, player.y, player.z) #logger.info("%s is now at coords (%s,%s,%s)", player.name, player.x, player.y, player.z)
await self.server.broadcast_message("%s is now at coords (%s,%s,%s, %s). Model: %s" % (player.name, player.x, player.y, player.z, player.o, model)) if player.opts["debug"]:
await player.send_message("%s is now at coords (%s,%s,%s, %s). Model: %s" % (player.name, player.x, player.y, player.z, player.o, model))
#await self.server.broadcast_message("(%s,%s,%s, %s,%s)" % (unknown4, unknown5, unknown6, unknown7, unknown9)) #await self.server.broadcast_message("(%s,%s,%s, %s,%s)" % (unknown4, unknown5, unknown6, unknown7, unknown9))
elif payload[0] == 0x3a: elif payload[0] == 0x3a:
@ -568,8 +559,14 @@ class Netserver(asyncio.DatagramProtocol):
logger.debug("Fuck that no player wtf man") logger.debug("Fuck that no player wtf man")
return return
await self.server.broadcast_event("on_player_left", player)
await self.server.remove_player(player) await self.server.remove_player(player)
await self.server.broadcast_gamedata(self.build_players_dpid())
plid = 0
for pplayer in self.server.players:
await self.server.broadcast_gamedata(b'\x3d' + struct.pack("<B", plid) + pplayer.name.encode("ascii") + b"\x00" * (33 - len(pplayer.name.encode("ascii"))), acknow=False) # playername
plid += 1
await self.server.broadcast_event("on_player_left", player)
elif payload[0] == 0x4d: elif payload[0] == 0x4d:
# CLIENT DOWNLOAD MAP # CLIENT DOWNLOAD MAP
player = self.get_player(session) player = self.get_player(session)
@ -614,6 +611,22 @@ class Netserver(asyncio.DatagramProtocol):
data = fh.read(512) data = fh.read(512)
def build_players_dpid(self, exceptplayer=False):
p1 = b'\x01' + struct.pack("<B", len(self.server.players))
for pplayer in self.server.players:
p1 += struct.pack("<L", pplayer.id)
for pplayer in self.server.players:
if pplayer.name == "[Server]":
continue
p1 += b'\x0e'
p1 += b"\x01\x00"
for pplayer in self.server.players:
if pplayer == exceptplayer or pplayer.name == "[Server]":
continue
p1 += struct.pack("<B", pplayer.team)
p1 += b'\x00\x00'
return p1
def send_packet(self, addr, packet): def send_packet(self, addr, packet):
self.remotesocket.sendto(packet.getvalue(), addr) self.remotesocket.sendto(packet.getvalue(), addr)
#logger.debug("%s:%s < %s", addr[0], addr[1], packet.getvalue().hex()) #logger.debug("%s:%s < %s", addr[0], addr[1], packet.getvalue().hex())

View File

@ -8,8 +8,9 @@ logger = setup_logger(__name__)
class Session: class Session:
def __init__(self, serversock): def __init__(self, server, serversock):
self.serversock = serversock self.serversock = serversock
self.server = server
self.ip = "" self.ip = ""
self.port = 0 self.port = 0
self.SessID = 0 self.SessID = 0
@ -52,7 +53,7 @@ class Session:
self.connect_retry_timer = self.setup_Connect_Retry_Timer() self.connect_retry_timer = self.setup_Connect_Retry_Timer()
async def send_gamedata(self, bPayload, **kwargs): async def send_gamedata(self, bPayload, **kwargs):
acknow = kwargs.get("acknow", True) acknow = kwargs.get("acknow", False)
dframe = DFrame() dframe = DFrame()
dframe.Command = DFrame.PACKET_COMMAND_DATA | DFrame.PACKET_COMMAND_RELIABLE | DFrame.PACKET_COMMAND_SEQUENTIAL | DFrame.PACKET_COMMAND_NEW_MSG | DFrame.PACKET_COMMAND_END_MSG dframe.Command = DFrame.PACKET_COMMAND_DATA | DFrame.PACKET_COMMAND_RELIABLE | DFrame.PACKET_COMMAND_SEQUENTIAL | DFrame.PACKET_COMMAND_NEW_MSG | DFrame.PACKET_COMMAND_END_MSG
if acknow: if acknow:

View File

@ -26,14 +26,17 @@ class Player(Entity):
self.phase = PlayerPhases.NONE self.phase = PlayerPhases.NONE
self.ping = 1 self.ping = 1
self.oid = 0 self.oid = 0
self.opts = {"debug": False}
async def change_team(self, newteam): async def change_team(self, newteam):
self.team = newteam self.team = newteam
await self.session.send_gamedata(b"\x10"+struct.pack("<B", self.team)+struct.pack("<L", self.id)+b"\x01\x00", acknow=False) await self.session.server.broadcast_event("on_player_change_team", self, self.team)
await self.session.send_gamedata(b"\x10"+struct.pack("<B", self.team)+struct.pack("<L", self.id)+b"\x01\x00", acknow=False)
await self.session.server.broadcast_gamedata(b"\x10"+struct.pack("<B", self.team)+struct.pack("<L", self.id)+b"\x01\x00")
#await self.session.server.broadcast_gamedata(b"\x10"+struct.pack("<B", self.team)+struct.pack("<L", self.id)+b"\x01\x00")
async def send_ping(self, ping): async def send_ping(self, ping):
await self.session.send_gamedata(b"\x2f\x02\x00\x00" + struct.pack("<H", ping) + b"\x00", acknow=False) await self.session.server.broadcast_gamedata(b"\x2f\x02\x00\x00" + struct.pack("<H", ping) + b"\x00")
async def send_message(self, message, type=ChatType.All, playerindex=0, color=ChatColor.Orange): async def send_message(self, message, type=ChatType.All, playerindex=0, color=ChatColor.Orange):
options = type | color options = type | color

View File

@ -15,7 +15,7 @@ class Commands:
if len(command) > 1 and command[0] == "team": if len(command) > 1 and command[0] == "team":
newteam = command[1].replace("\x00", "") newteam = command[1].replace("\x00", "")
print("Changing team of %s to %s" % (player.name, newteam)) print("Changing team of %s to %s" % (player.name, newteam))
await self.server.broadcast_message("%s switched to team %s" % (player.name, newteam)) await self.server.broadcast_message("%s switched to team %s using command" % (player.name, newteam))
await player.change_team(int(newteam)) await player.change_team(int(newteam))
if len(command) > 1 and command[0] == "ping": if len(command) > 1 and command[0] == "ping":
@ -70,6 +70,14 @@ class Commands:
await self.server.broadcast_message("Changing model of "+command[1]+" to "+command[2]+"") await self.server.broadcast_message("Changing model of "+command[1]+" to "+command[2]+"")
await self.server.change_model(self.server.get_player_by_index(int(command[1])), int(command[2])) await self.server.change_model(self.server.get_player_by_index(int(command[1])), int(command[2]))
if command[0] == "debug":
if player.opts["debug"]:
player.opts["debug"] = False
await player.send_message("Debug disabled")
else:
player.opts["debug"] = True
await player.send_message("Debug enabled")
def setup(server): def setup(server):
plugin = Commands(server) plugin = Commands(server)

View File

@ -27,22 +27,22 @@ class Server:
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")
fake_session = Session(socket.socket(socket.AF_INET, socket.SOCK_DGRAM)) fake_session = Session(self, socket.socket(socket.AF_INET, socket.SOCK_DGRAM))
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("[Server]", fake_session)] self.players = [Player("[Server]", fake_session)]
fake_player = Session(socket.socket(socket.AF_INET, socket.SOCK_DGRAM)) fake_player = Session(self, socket.socket(socket.AF_INET, socket.SOCK_DGRAM))
fake_player.ip = "127.0.0.1" fake_player.ip = "127.0.0.1"
fake_player.port = 3334 fake_player.port = 3334
self.players.append(Player("Bot 1", fake_player)) self.players.append(Player("Bot 1", fake_player))
fake_player = Session(socket.socket(socket.AF_INET, socket.SOCK_DGRAM)) fake_player = Session(self, socket.socket(socket.AF_INET, socket.SOCK_DGRAM))
fake_player.ip = "127.0.0.1" fake_player.ip = "127.0.0.1"
fake_player.port = 3334 fake_player.port = 3334
self.players.append(Player("Bot 2", fake_player)) self.players.append(Player("Bot 2", fake_player))
fake_player = Session(socket.socket(socket.AF_INET, socket.SOCK_DGRAM)) fake_player = Session(self, socket.socket(socket.AF_INET, socket.SOCK_DGRAM))
fake_player.ip = "127.0.0.1" fake_player.ip = "127.0.0.1"
fake_player.port = 3334 fake_player.port = 3334
self.players.append(Player("Bot 3", fake_player)) self.players.append(Player("Bot 3", fake_player))
@ -74,7 +74,6 @@ class Server:
async def remove_player(self, player): async def remove_player(self, player):
self.players.remove(player) self.players.remove(player)
await self.broadcast_event("on_player_left", player)
def add_plugin(self, plugin): def add_plugin(self, plugin):
self._plugins.append(plugin) self._plugins.append(plugin)
@ -141,6 +140,12 @@ class Server:
continue continue
await player.session.send_gamedata(payload, **kwargs) await player.session.send_gamedata(payload, **kwargs)
async def broadcast_gamedata_except(self, player, payload, **kwargs):
for pplayer in self.players:
if pplayer.name == "[Server]" or pplayer == player:
continue
await pplayer.session.send_gamedata(payload, **kwargs)
async def broadcast_message_except(self, player, text, color=ChatColor.Yellow, type=ChatType.All): async def broadcast_message_except(self, player, text, color=ChatColor.Yellow, type=ChatType.All):
for pplayer in self.players: for pplayer in self.players:
if pplayer.name == "[Server]" or pplayer == player: if pplayer.name == "[Server]" or pplayer == player:
@ -264,7 +269,7 @@ if __name__ == '__main__':
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()
listen = loop.create_datagram_endpoint(lambda: Netserver(server), local_addr=(server.listen_ip, server.listen_port)) listen = loop.create_datagram_endpoint(lambda: Netserver(server), local_addr=(server.listen_ip, server.listen_port))
transport, protocol = loop.run_until_complete(listen) transport, protocol = loop.run_until_complete(listen)
loop.create_task(server.ask_command()) #loop.create_task(server.ask_command())
try: try:
loop.run_forever() loop.run_forever()
except KeyboardInterrupt: except KeyboardInterrupt: