Added more commands

This commit is contained in:
Amazed 2019-02-19 01:01:31 +01:00
parent 556c9dcc69
commit d962495e48
7 changed files with 207 additions and 170 deletions

View File

@ -123,13 +123,12 @@ class Netserver(asyncio.DatagramProtocol):
appdata.putShort(self.server.points_per_kill)
appdata.write(b'\x00\x00') # original: 0000 - does not seem to affect client
appdata.putShort(self.server.detente_time)
appdata.write(
b'\x9f\xb2\x42\xec') # Seems to be a checksum of current map OR linked to the number of chars in the map name
appdata.write(self.server.currentmap.checksum) # Seems to be a checksum of current map OR linked to the number of chars in the map name
appdata.write(self.server.currentmap.mapname.encode("ascii"))
appdata.write(b'\x00' * (32 - len(self.server.currentmap.mapname)))
er.ApplicationReservedData = appdata.getvalue()
logger.debug("Current map: %s", self.server.currentmap.mapname)
logger.debug("Current map: %s, checksum: %s", self.server.currentmap.mapname, self.server.currentmap.checksum)
er.ApplicationReservedData += b'\x00' * (32 - len(self.server.currentmap.mapname))
self.send_packet(addr, er.to_packet())
except Exception:
@ -220,7 +219,8 @@ class Netserver(asyncio.DatagramProtocol):
sack_sent = True
# release lock for new packet to be sent
session.lock.release()
if session.lock.locked():
session.lock.release()
# WIP: The bNSeq, bNRcv, optional selective acknowledgment (SACK), and optional send mask fields are then processed by using the standard rules in sections 3.1.5.2.1 through 3.1.5.2.4
# TODO: A successfully validated SACK packet SHOULD count as a valid receive and thus restart the KeepAlive timer
@ -274,10 +274,13 @@ class Netserver(asyncio.DatagramProtocol):
if dframe.Command & DFrame.PACKET_COMMAND_POLL:
#logger.debug("Sending SACK")
#session.send_cframe_sack()
session.send_cframe_sack()
pass
session.next_expected_seq += 1
if session.next_expected_seq == 255:
session.next_expected_seq = 0
else:
session.next_expected_seq += 1
if dframe.Payload:
await self.handle_game_packet(session, dframe.Payload)
else:
@ -336,11 +339,12 @@ class Netserver(asyncio.DatagramProtocol):
appdata.putShort(self.server.points_per_kill)
appdata.write(b'\x00\x00') # original: 0000 - does not seem to affect client
appdata.putShort(self.server.detente_time)
appdata.write(b'\x9f\xb2\x42\xec') # Seems to be a checksum of current map OR linked to the number of chars in the map name
appdata.write(self.server.currentmap.checksum) # Seems to be a checksum of current map OR linked to the number of chars in the map name
appdata.write(self.server.currentmap.mapname.encode("ascii"))
appdata.write(b'\x00' * (32 - len(self.server.currentmap.mapname)))
d.ApplicationReservedData = appdata.getvalue()
session.send(d)
logger.debug("%s:%s > %s (GAMEDATA)", session.ip, session.port, appdata.getvalue().hex())
player.phase = PlayerPhases.DN_SEND_CONNECT_INFO
elif payload[0] == 0xc3:
@ -371,27 +375,6 @@ class Netserver(asyncio.DatagramProtocol):
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]
await player.session.send_gamedata(b'\x3d\x01'+player.name.encode("ascii")+b"\x00"*(33-len(player.name.encode("ascii"))), acknow=True) # playername
"""
player.session.send_gamedata(b'\x0f\x56\xab\x31\x96\x06\x00\x00\x00\x00\x00\x00\x00\x00') # unknown
player.session.send_gamedata(b'\x10\x02\x56\xab\x31\x96\x00\x00\x00\x00\x00\x00\x00\x00') # unknown
player.session.send_gamedata(b'\x29\x28\x00\x00\x80\x32\x00\x00\x80\x05\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00') # unknown
player.session.send_gamedata(b'\x39\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') # unknown
player.session.send_gamedata(b'\x39\x01\x02\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') # unknown
player.session.send_gamedata(b'\x0f\x56\xab\x31\x96\x07\x00\x00\x00\x00\x00\x00\x00\x00') # unknown
player.session.send_gamedata(b'\x0a\x12\x00\x00\x00\x00\x28\x10\x03\x10\x12\x00\x00\x00\xc1\xff\x41\xff\x00', acknow=True) # unknown
player.session.send_gamedata(b'\x0f\x56\xab\x31\x96\x08\x00\x00\x00\x00\x00\x00\x00\x00', acknow=True) # unknown
player.session.send_gamedata(b'\x0a\x12\x00\x00\x00\x00\x2c\x10\x03\x10\x12\x00\x00\x00\x08\x00\xb6\x01\x0a\x14\x00\x00\x00\x00\x2d\x10\x03\x01\x12\x00\x00\x00\xd4\xfc\x9b\xfd\x00\x00\x00', acknow=True) # unknown
#\x00
player.session.send_gamedata(b'\x2f\x02\x00\x00\xbe\x00\x00\x00\x00\x00\x00\x00\x00\x00', acknow=True) # unknown
player.session.send_gamedata(b'\x0a\x12\x00\x00\x00\x00\x2e\x10\x03\x10\x12\x00\x00\x00\xa8\xfd\x2d\x03\x0a\x14\x00\x00\x00\x00\x2e\x10\x03\x01\x12\x00\x00\x00\x60\xfd\x14\x03\x00\x00\x00', acknow=True) # unknown
player.session.send_gamedata(b'\x0a\x14\x00\x00\x00\x00\x28\x10\x03\x01\x12\x00\x00\x00\xbf\xff\x3f\xff\x00\x00\x00', acknow=True) # unknown
player.session.send_gamedata(b'\x0a\x12\x00\x00\x00\x00\x2a\x10\x03\x10\x12\x00\x00\x00\x73\x01\x42\x02\x0a\x14\x00\x00\x00\x00\x2a\x10\x03\x01\x12\x00\x00\x00\xbe\x01\x8c\x02\x00\x00\x00', acknow=True) # unknown
player.session.send_gamedata(b'\x2f\x02\x00\x00\xc2\x00\x00\x00\x00\x00\x00\x00\x00\x00',acknow=True) # unknown
player.session.send_gamedata(b'\x0a\x14\x00\x00\x00\x00\x2c\x10\x03\x01\x12\x00\x00\x00\x06\x00\xb5\x01\x00\x00\x00', acknow=True) # unknown
player.session.send_gamedata(b'\x0a\x12\x00\x00\x00\x00\x2e\x10\x03\x10\x12\x00\x00\x00\xa4\xfd\x2c\x03\x00',acknow=True) # unknown
player.session.send_gamedata(b'\x2f\x02\x00\x00\xc2\x00\x00\x00\x00\x00\x00\x00\x00\x00', acknow=True) # unknown
"""
elif payload[0] == 0x0f:
player = self.get_player(session)
if not player:
@ -410,14 +393,34 @@ class Netserver(asyncio.DatagramProtocol):
out.putULong(playerid)
out.putByte(status)
await player.session.send_gamedata(out.getvalue(), acknow=False)
elif payload[0] == 0x2c:
elif payload[0] == 0x2c: # CMSG_CHANGE_TEAM: team (byte), player id (int), unknown (byte)
player = self.get_player(session)
if not player:
logger.debug("Fuck that no player wtf man")
return
# assign team?
await player.session.send_gamedata(b"\x10"+struct.pack("<B", player.team)+struct.pack("<L", player.id)+b"\x00\x00", acknow=False)
p = Packet(payload)
opcode = p.getByte()
team = p.getByte()
playerid = p.getULong()
unknown = p.getByte()
await player.change_team(team-128)
await self.server.broadcast_event("on_player_change_team", player, player.team)
elif payload[0] == 0x35: # CMSG_SEND_CHAT_MESSAGE: messagetype? (byte), team? (byte), message (string)
player = self.get_player(session)
if not player:
logger.debug("Fuck that no player wtf man")
return
p = Packet(payload)
opcode = p.getByte()
type = p.getByte()
team = p.getByte()
message = p.read().decode("utf8").replace("\x00", "")
await self.server.broadcast_event("on_player_chat", player, type, team, message)
elif payload[0] == 0x2a:
player = self.get_player(session)
if not player:
@ -435,10 +438,12 @@ class Netserver(asyncio.DatagramProtocol):
logger.debug("Fuck that no player wtf man")
return
playerping = 1
await player.session.send_gamedata(b"\x2f\x02\x00\x00" + struct.pack("<H", playerping) + b"\x00",acknow=False) # acknow=True
await player.session.send_gamedata(b"\x2f\x02\x00\x00" + struct.pack("<H", playerping) + b"\x00", acknow=False) # acknow=True
for i in range(0x06):
ack = (i % 2 == 0)
await player.session.send_gamedata(b"\x04" + struct.pack("<B", i) + b"\x00\x00\x00\x00" + struct.pack("<B", i+0x07) + b"\x00\x00\x00",acknow=ack)
# spawn position is sent by client wtf
await player.session.send_gamedata(b"\x1a\xee\x02\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x83\x5f\xa4\x44\x00\xf9\xa3\xc2\x00\x00\x00\x00\xff\xff\x33\x43\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x9e\xdc\x07\x00", acknow=True)
await player.session.send_gamedata(b"\x19\x96\x03\x00\x10\x00\x00\x04\x00\x0d\x00\x00\x83\x5f\xa4\x44\x00\xf9\xa3\xc2\x00\x00\x00\x00\xff\xff\x33\x43\x00\x00\x7a\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00", acknow=False)
await player.session.send_gamedata(b"\x39"+b"\x00"*21, acknow=True)
@ -448,122 +453,34 @@ class Netserver(asyncio.DatagramProtocol):
await player.session.send_gamedata(b"\x3e\x00\x00\x00\x00\x00", acknow=True)
await player.session.send_gamedata(b"\x3f\x00\x00", acknow=False)
await player.session.send_gamedata(b"\x0e\x00", acknow=True)
await player.session.send_gamedata(b"\x10" + struct.pack("<B", player.team) + struct.pack("<L", player.id) + b"\x00\x00", acknow=False)
elif payload[0] == 0x0a and payload[1] == 0x32:
player = self.get_player(session)
if not player:
logger.debug("Fuck that no player wtf man")
return
p = Packet(payload)
opcode = p.getShort()
unknown1 = p.getULong()
unknown2 = p.getULong()
unknown3 = p.getULong()
playerx = p.getFloat()
playery = p.getFloat()
playerz = p.getFloat()
unknown4 = p.getULong()
unknown5 = p.getULong()
unknown6 = p.getULong()
unknown7 = p.getULong()
unknown8 = p.getULong()
unknown9 = p.getULong()
player.x = playerx
player.y = playery
player.z = playerz
return
await player.session.send_gamedata(
b"\x0a\x12\x00\x00\x00\x00\x71\xa6\x08\x10\x12\x00\x00\x00\xde\xfe\x83\xfd\x00",
acknow=False) # acknow=True
await player.session.send_gamedata(
b"\x0a\x12\x00\x00\x00\x00\x68\xa6\x08\x10\x12\x00\x00\x00\x50\xff\x5a\xfd\x00",
acknow=False) # acknow=True
await player.session.send_gamedata(b"\x4b\xe0\xe8\x0c\x00\x00\x8a\x14\x00\x00", acknow=False) # acknow=True
await player.session.send_gamedata(
b"\x0a\x12\x00\x00\x00\x00\xa9\xa5\x08\x01\x2d\x00\x00\x00\x25\x54\x05\x46\x00",
acknow=False) # acknow=True
await player.session.send_gamedata(
b"\x0a\x16\x00\x00\x00\x00\x53\xa6\x08\x04\x15\x00\x00\x00\xc2\xfd\x6d\x01\x40\x00\xf4\xff\x0a\x14\x00\x00\x00\x00\x71\xa6\x08\x01\x12\x00\x00\x00\xde\xfe\x81\xfd\x00\x00\x00",
acknow=False) # acknow=True
await player.session.send_gamedata(
b"\x0a\x14\x00\x00\x00\x00\x68\xa6\x08\x01\x12\x00\x00\x00\x51\xff\x5c\xfd\x00\x00\x00",
acknow=False) # acknow=True
playerping = 1
await player.session.send_gamedata(b"\x2f\x02\x00\x00" + struct.pack("<H", playerping) + b"\x00",
acknow=False) # acknow=True
await player.session.send_gamedata(
b"\x0a\x12\x00\x00\x00\x00\x57\xa6\x08\x10\x12\x00\x00\x00\x2e\xff\xa7\xfd\x00",
acknow=False) # acknow=True
await player.session.send_gamedata(
b"\x0a\x14\x00\x00\x00\x00\x57\xa6\x08\x01\x12\x00\x00\x00\x5b\xff\x75\xfd\x00\x00\x00",
acknow=False) # acknow=True
await player.session.send_gamedata(
b"\x0a\x16\x00\x00\x00\x00\x50\xa6\x08\x04\x15\x00\x00\x00\xe2\xfd\x51\x01\x3d\x00\xed\xff\x00",
acknow=False) # acknow=True
await player.session.send_gamedata(
b"\x0a\x16\x00\x00\x00\x00\x55\xa6\x08\x04\x15\x00\x00\x00\xe5\xfd\x40\x01\xe5\xff\xf8\xff\x00",
acknow=False) # acknow=True
await player.session.send_gamedata(
b"\x0a\x12\x00\x00\x00\x00\x72\xa6\x08\x10\x12\x00\x00\x00\xf2\xfe\x79\xfd\x0a\x14\x00\x00\x00\x00\x72\xa6\x08\x01\x12\x00\x00\x00\x28\xff\x48\xfd\x00\x00\x00",
acknow=False) # acknow=True
await player.session.send_gamedata(
b"\x0a\x16\x00\x00\x00\x00\x4e\xa6\x08\x04\x15\x00\x00\x00\xc8\xfd\x2f\x01\xa1\xff\x06\x00\x00",
acknow=False) # acknow=True
await player.session.send_gamedata(
b"\x0a\x12\x00\x00\x00\x00\xa9\xa5\x08\x01\x2d\x00\x00\x00\x19\x3d\x09\x46\x00",
acknow=False) # acknow=True
await player.session.send_gamedata(bytes.fromhex("0a120000000057a608101200000031ffa4fd00"), acknow=False)
await player.session.send_gamedata(bytes.fromhex("0a120000000057a608101200000031ffa4fd00"), acknow=False)
await player.session.send_gamedata(bytes.fromhex("0a160000000056a6080415000000b1fd4001c8ff120000"),
acknow=False)
await player.session.send_gamedata(bytes.fromhex("0a160000000056a6080415000000b1fd4001c8ff120000"),
acknow=False)
await player.session.send_gamedata(bytes.fromhex("0a12000000005ca608101200000077ff03fe00"), acknow=False)
await player.session.send_gamedata(bytes.fromhex("0a14000000005ca608011200000050ffd6fd000000"),
acknow=False)
await player.session.send_gamedata(bytes.fromhex("0a160000000047a6080415000000bafd1001d0ff0a0000"),
acknow=False)
await player.session.send_gamedata(bytes.fromhex("0a120000000072a6081012000000f5fe75fd00"), acknow=False)
await player.session.send_gamedata(bytes.fromhex("0a160000000052a6080415000000c9fd45011800080000"),
acknow=False)
await player.session.send_gamedata(bytes.fromhex("0a16000000004ca6080415000000c1fdab01e7ff0d0000"),
acknow=False)
await player.session.send_gamedata(bytes.fromhex("0a140000000057a608011200000030ffa6fd000000"),
acknow=False)
await player.session.send_gamedata(bytes.fromhex("2b00000000fa5e5b4500"), acknow=False)
await player.session.send_gamedata(bytes.fromhex(
"0a12000000005ca608101200000074fffffd0a12000000005da608101200000092ff6afd0a140000000072a6080112000000f4fe77fd00000a14000000005da6080112000000a7ff80fd000000"),
acknow=False)
await player.session.send_gamedata(bytes.fromhex("0a1200000000a9a508012d000000fe280d4600"), acknow=False)
await player.session.send_gamedata(bytes.fromhex("091200000000c9a50802260000000073a60800"), acknow=False)
await player.session.send_gamedata(bytes.fromhex("0a140000000073a608011200000009ff97fd000000"),
acknow=False)
await player.session.send_gamedata(bytes.fromhex("2e070700000000000000"), acknow=False)
await player.session.send_gamedata(bytes.fromhex("0a160000000054a6080415000000befd88010d00e4ff00"),
acknow=False)
await player.session.send_gamedata(bytes.fromhex("0a16000000004aa6080415000000b0fd5301b4ffb4ff00"),
acknow=False)
await player.session.send_gamedata(
bytes.fromhex("0a120000000068a608101200000075ff7dfd0a140000000068a608011200000051ff5cfd000000"),
acknow=False)
await player.session.send_gamedata(bytes.fromhex("0a12000000005da608101200000095ff6dfd00"), acknow=False)
await player.session.send_gamedata(bytes.fromhex(
"0a16000000004ba6080415000000e7fd3f01e0ffa6ff0a160000000049a6080415000000b5fd6101c0ffe5ff00"),
acknow=False)
await player.session.send_gamedata(bytes.fromhex("0a14000000005ca608011200000076ff00fe000000"),
acknow=False)
await player.session.send_gamedata(bytes.fromhex("0a120000000068a608101200000071ff79fd00"), acknow=False)
await player.session.send_gamedata(bytes.fromhex("090e00000000c9a508012600000000"), acknow=False)
await player.session.send_gamedata(bytes.fromhex("0a1200000000a9a508012d000000c016114600"), acknow=False)
await player.session.send_gamedata(bytes.fromhex("0a16000000004fa6080415000000b2fd8801c9ffceff00"),
acknow=False)
await player.session.send_gamedata(bytes.fromhex("0a14000000005da608011200000094ff6cfd000000"),
acknow=False)
await player.session.send_gamedata(bytes.fromhex("0a160000000048a608041500000011fe5201e2ff2c0000"),
acknow=False)
await player.session.send_gamedata(bytes.fromhex("0a120000000073a6081012000000c0fe5efd00"), acknow=False)
await player.session.send_gamedata(bytes.fromhex("0a140000000073a608011200000009ff83fd000000"),
acknow=False)
await player.session.send_gamedata(bytes.fromhex("0a120000000071a6081012000000fbfec2fd00"), acknow=False)
await player.session.send_gamedata(bytes.fromhex("0a140000000071a6080112000000defe81fd000000"),
acknow=False)
await player.session.send_gamedata(bytes.fromhex("0a140000000068a608011200000072ff7afd000000"),
acknow=False)
for i in range(0x7f):
if i >= 0x5c:
await player.session.send_gamedata(bytes.fromhex(
"04" + struct.pack("<B", i).hex() + "00000000" + struct.pack("<B", (
0xa4 + i) % 0xff).hex() + "a60800"), acknow=False)
else:
await player.session.send_gamedata(bytes.fromhex(
"04" + struct.pack("<B", i).hex() + "00000000" + struct.pack("<B", 0xa4 + i).hex() + "a50800"),
acknow=False)
await player.session.send_gamedata(b"\x05\x01\x7b\x02\x00\x03\x00\x00\x00\x00", acknow=False) # acknow=True
# 0f packet
# final packet
await player.session.send_gamedata(b"\x2b\x00\x00\x00\x00\xa0\xe8\x5a\x45\x00", acknow=False) # acknow=True
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)" % (player.name, player.x, player.y, player.z))
def send_packet(self, addr, packet):

View File

@ -59,4 +59,21 @@ class GameTypes:
GTypeStone = 0x08
GTypeWood = 0x09
Crash = 0x0a
GTypeNull = 0x0c
GTypeNull = 0x0c
class ChatColor:
Black = 0x00
Cyan = 0x01 # or 0x06
Yellow = 0x02
LightBlue = 0x03
Orange = 0x04
DarkBlue = 0x05
White = 0x07
Blue = 0x0c
class ChatType:
All = 0x00
AllFromPlayer = 0xc0
TeamFromPlayer = 0xf0

View File

@ -19,6 +19,18 @@ class Map:
self.checksum = Map.checksum(mappath)
@staticmethod
def checksum(mapname):
def checksum(mappath):
# TODO
return 1
if mappath == "Three Way Island - Canyons.gck":
return b"\x9c\x53\xf4\xdd"
if mappath == "test1.gck":
return b"\x9f\xb2\x42\xec"
if mappath == "test.gck":
return b"\x48\x52\x33\x23"
# \x00\x00\x00\x00: [None]
# \x00\x00\x00\x01: <custom map>
# \x9c\x53\xf4\xdd: Three Way Island - Canyons
# \x1e\xe9\x39\xe1: Still Winter
# \x9f\xb2\x42\xec: testv1
# \x48\x52\x33\x23: testv2
return b"\x00\x00\x00\x00"

View File

@ -1,5 +1,7 @@
from .entity import Entity
import random
import struct
from . import ChatColor, ChatType
class PlayerPhases:
@ -16,7 +18,20 @@ class Player(Entity):
super().__init__()
self.name = name
self.session = session
self.team = 1
self.team = 4
self.score = 0
self.id = random.getrandbits(32)
self.phase = PlayerPhases.NONE
self.ping = 1
async def change_team(self, newteam):
self.team = newteam
await self.session.send_gamedata(b"\x10"+struct.pack("<B", self.team)+struct.pack("<L", self.id)+b"\x00\x00", acknow=False)
async def send_ping(self, ping):
await self.session.send_gamedata(b"\x2f\x02\x00\x00" + struct.pack("<H", ping) + b"\x00", acknow=False)
async def send_message(self, message, type=ChatType.All, playerindex=0, color=ChatColor.Orange):
options = type | color
playeri = 0x80 + playerindex
await self.session.send_gamedata(b"\x35" + struct.pack("<B", playeri)+ struct.pack("<B", options) + message.encode("utf8") + b"\x00\x00", acknow=False)

64
plugins/commands.py Normal file
View File

@ -0,0 +1,64 @@
from giants import ChatColor
import asyncio
import struct
class Commands:
def __init__(self, server):
self.server = server
async def on_player_chat(self, player, type, team, message):
await self.server.broadcast_message("%s (%s,%s): %s" % (player.name, type, team, message), color=ChatColor.Yellow)
print(message)
command = message.split(" ")
if len(command) > 1 and command[0] == "team":
newteam = command[1].replace("\x00", "")
print("Changing team of %s to %s" % (player.name, newteam))
await self.server.broadcast_message("%s switched to team %s" % (player.name, newteam))
await player.change_team(int(newteam))
if len(command) > 1 and command[0] == "ping":
newping = command[1].replace("\x00", "")
print("Changing ping of %s to %s" % (player.name, newping))
await self.server.broadcast_message("%s set his ping to %s" % (player.name, newping))
await player.send_ping(int(newping))
if command[0] == "ping":
print("ping function")
await self.server.broadcast_message("pong")
if command[0] == "colors":
# color codes seem to go from 01 to 0F, loop and show each value:
for i in range(1, 0xf + 1):
print("Trying value %s" % i)
await player.send_message("Color %s" % i, color=i)
await asyncio.sleep(2) # sleep between each value to see what value makes the client crash
if command[0] == "chattypes":
# type codes seem to go from 00 to 0F, loop and show each value: CRASH
for i in range(0, 0xf+1):
print("Trying value %s" % i)
await self.server.broadcast_message("Type %s" % i, type=i)
await asyncio.sleep(2) # sleep between each value to see what value makes the client crash
if command[0] == "doomchat":
# tries every value of first byte and second byte
for i in range(3,0xff+1):
for j in range(0, 0x81):
if i == 0 and j == 2:
break # ;)
message = "(%s, %s)" % (i, j)
print(message)
await player.session.send_gamedata(b"\x35" + struct.pack("<B", i)+ struct.pack("<B", j) + message.encode("utf8") + b"\x00\x00", acknow=False)
await asyncio.sleep(0.1) # sleep between each value to see what value makes the client crash
if command[0] == "die" and len(command) > 1:
diemethod = int(command[1])
await player.send_message("Death by id: %s" % diemethod)
await player.session.send_gamedata(bytes.fromhex("0b1a0000000002070000a5b0d4c35d9714c450abef354a68fb410914000000020700000402000000")+struct.pack("<L",diemethod)+bytes.fromhex("0000"))
def setup(server):
plugin = Commands(server)
server.add_plugin(plugin)

View File

@ -1,6 +1,4 @@
import random
import asyncio
import struct
class Greetings:
def __init__(self, server):
@ -9,20 +7,14 @@ class Greetings:
async def on_player_join(self, player):
await self.server.broadcast_message(random.choice(self.messages) % player.name)
#await Greetings.send_ping(player)
@staticmethod
async def send_ping(player):
while 1:
for ping in range(0, 999):
await player.session.send_gamedata(b"\x2f\x02\x00\x00" + struct.pack("<H", ping) + b"\x00",acknow=True) # acknow=True
for ping in range(999, 0, -1):
await player.session.send_gamedata(b"\x2f\x02\x00\x00" + struct.pack("<H", ping) + b"\x00",acknow=True) # acknow=True
async def on_map_change(self, newmap):
await self.server.broadcast_message("You are now playing on "+newmap.mapname)
async def on_player_change_team(self, player, newteam):
await self.server.broadcast_message("%s switched to team %s" % (player.name, newteam))
def setup(server):
plugin = Greetings(server)
server.add_plugin(plugin)
server.add_plugin(plugin)

View File

@ -5,10 +5,11 @@ from dpnet.session import Session
import socket
import importlib
import os
from giants import Teams, GameTypes
from giants import Teams, GameTypes, ChatColor, ChatType
from utils.logger import setup_logger
import traceback
import asyncio
from aioconsole import ainput
logger = setup_logger(__name__)
@ -20,7 +21,7 @@ class Server:
self.register_with_ms = kwargs.get("register", False)
self.teams = kwargs.get("teams", Teams.MvM)
self.game_type = kwargs.get("gametype", GameTypes.TeamDeathmatchWithFullBase)
self.currentmap = kwargs.get("map", Map("Three Way Island - Canyons.gck"))
self.currentmap = kwargs.get("map", Map("test.gck"))
self.maxplayers = kwargs.get("maxplayers", 20)
self.name = kwargs.get("name", "Default Server Name")
@ -29,6 +30,11 @@ class Server:
fake_session.port = 3333
self.players = [Player("[Server]", fake_session)]
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))
self.accept_new_players = True
self.version = 1.497
self.points_per_kill = 1
@ -46,7 +52,7 @@ class Server:
async def add_player(self, player):
self.tempplayers.remove(player)
self.players.append(player)
await self._broadcast_event("on_player_join", player)
await self.broadcast_event("on_player_join", player)
# todo: remove
def create_temp_player(self, player):
@ -54,7 +60,7 @@ class Server:
async def remove_player(self, player):
self.players.remove(player)
await self._broadcast_event("on_player_left", player)
await self.broadcast_event("on_player_left", player)
def add_plugin(self, plugin):
self._plugins.append(plugin)
@ -62,11 +68,11 @@ class Server:
async def change_map(self, mappath):
try:
self.currentmap = Map(mappath)
await self._broadcast_event("on_map_change", self.currentmap)
await self.broadcast_event("on_map_change", self.currentmap)
except Exception:
logger.error("Could not change map")
async def _broadcast_event(self, event, *args):
async def broadcast_event(self, event, *args):
logger.debug("Broadcasting event "+event)
for plugin in self._plugins:
if hasattr(plugin, event):
@ -97,19 +103,33 @@ class Server:
logger.warning("Could not load plugin "+plugin)
traceback.print_exc()
async def broadcast_message(self, text):
async def broadcast_message(self, text, color=ChatColor.Orange, type=ChatType.All):
for player in self.players:
if player.name == "[Server]":
continue
await player.session.send_gamedata(b'\x35\x80\x81'+text.encode("ascii")+b'\x00\x00', acknow=False)
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()
if __name__ == '__main__':
server = Server(name="giantsd", maxplayers=20, register=False)
server = Server(name="giantsd", maxplayers=20, register=False) #, 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)
loop.create_task(server.ask_command())
try:
loop.run_forever()
except KeyboardInterrupt: