mirror of
https://github.com/Wesley-DeMontigny/WLUS.git
synced 2026-02-11 12:38:40 -06:00
217 lines
8.7 KiB
Python
217 lines
8.7 KiB
Python
from ServerUtilities import *
|
|
from GameManager import *
|
|
from Enum import *
|
|
import time
|
|
from core import GameServer, CString
|
|
from AccountManager import Account
|
|
from xml.etree import ElementTree
|
|
from LDF import LDF, from_ldf
|
|
import copy
|
|
import zlib
|
|
|
|
def HandleHandshake(Server : GameServer, data : bytes, address : Address):
|
|
stream = ReadStream(data)
|
|
clientVersion = stream.read(c_ulong)
|
|
|
|
Server.send(getHandshake(clientVersion, 4), address)
|
|
|
|
def HandleSessionKey(Server : GameServer, data : bytes, address : Address):
|
|
stream = ReadStream(data)
|
|
username = stream.read(str, allocated_length=33)
|
|
userKey = stream.read(str, allocated_length=33)
|
|
|
|
session = Server.Game.getSessionByAddress(address)
|
|
if(session is not None and session.userKey == userKey and session.accountUsername == username):
|
|
print(address, "sent the following valid key:", userKey)
|
|
session.State = SessionState.CharacterScreen
|
|
else:
|
|
Server.send(getDisconnect(DisconnectionReasons.InvalidSessionKey.value), address)
|
|
|
|
def HandleMinifigListRequest(Server : GameServer, data : bytes, address : Address):
|
|
session = Server.Game.getSessionByAddress(address)
|
|
if(session.State == SessionState.CharacterScreen):
|
|
characters = Server.Game.getAccountByUsername(session.accountUsername).Characters
|
|
packet = WriteStream()
|
|
writeHeader(packet, PacketHeader.MinifigureList)
|
|
packet.write(c_uint8(len(characters)))
|
|
packet.write(c_uint8(0))
|
|
for character in characters:
|
|
packet.write(c_longlong(character.ObjectConfig["ObjectID"]))#Object ID
|
|
packet.write(c_ulong(0))
|
|
packet.write(character.ObjectConfig["Name"], allocated_length=33)#Character Name
|
|
packet.write("", allocated_length=33)#Name to show up in paranthesis
|
|
packet.write(c_bool(False))#Name rejected
|
|
packet.write(c_bool(False))#Free to play
|
|
packet.write(CString("", allocated_length=10))#Unknown
|
|
packet.write(c_ulong(character.ObjectConfig["ShirtColor"]))
|
|
packet.write(c_ulong(character.ObjectConfig["ShirtStyle"]))
|
|
packet.write(c_ulong(character.ObjectConfig["PantsColor"]))
|
|
packet.write(c_ulong(character.ObjectConfig["HairStyle"]))
|
|
packet.write(c_ulong(character.ObjectConfig["HairColor"]))
|
|
packet.write(c_ulong(character.ObjectConfig["lh"]))
|
|
packet.write(c_ulong(character.ObjectConfig["rh"]))
|
|
packet.write(c_ulong(character.ObjectConfig["Eyebrows"]))
|
|
packet.write(c_ulong(character.ObjectConfig["Eyes"]))
|
|
packet.write(c_ulong(character.ObjectConfig["Mouth"]))
|
|
packet.write(c_ulong(0))
|
|
packet.write(c_uint16(character.Zone))
|
|
packet.write(c_uint16(0))#MapInstance
|
|
packet.write(c_ulong(0))#MapClone
|
|
packet.write(c_ulonglong(0))
|
|
equippedItems = character.Inventory.getEquippedItems()
|
|
packet.write(c_ushort(len(equippedItems)))
|
|
for item in equippedItems:
|
|
packet.write(c_ulong(item["LOT"]))
|
|
Server.send(packet, address)
|
|
|
|
def HandleMinifigureCreation(Server : GameServer, data : bytes, address : Address):
|
|
session : Session = Server.Game.getSessionByAddress(address)
|
|
account : Account = Server.Game.getAccountByUsername(session.accountUsername)
|
|
stream = ReadStream(data)
|
|
name = stream.read(str, allocated_length=33)
|
|
predefName1 = stream.read(c_ulong)
|
|
predefName2 = stream.read(c_ulong)
|
|
predefName3 = stream.read(c_ulong)
|
|
stream.read(bytes, allocated_length=9)
|
|
ShirtColor = stream.read(c_ulong)
|
|
ShirtStyle = stream.read(c_ulong)
|
|
PantsColor = stream.read(c_ulong)
|
|
HairStyle = stream.read(c_ulong)
|
|
HairColor = stream.read(c_ulong)
|
|
lh = stream.read(c_ulong)
|
|
rh = stream.read(c_ulong)
|
|
Eyebrows = stream.read(c_ulong)
|
|
Eyes = stream.read(c_ulong)
|
|
Mouth = stream.read(c_ulong)
|
|
account.CreateMinifigure(name, ShirtColor, ShirtStyle, PantsColor, HairColor, HairStyle, lh, rh, Eyebrows, Eyes, Mouth)
|
|
time.sleep(.5)
|
|
SendCreationResponse(Server, address, MinifigureCreationResponse.Success)
|
|
HandleMinifigListRequest(Server, b"", address)
|
|
|
|
def HandleMinifigureDeletion(Server : GameServer, data : bytes, address : Address):
|
|
stream = ReadStream(data)
|
|
session : Session = Server.Game.getSessionByAddress(address)
|
|
ObjectID = stream.read(c_longlong)
|
|
account : Account = Server.Game.getAccountByUsername(session.accountUsername)
|
|
for i in range(len(account.Characters)):
|
|
if(account.Characters[i].ObjectConfig["ObjectID"] == ObjectID):
|
|
del account.Characters[i]
|
|
print("Deleted Character {}".format(ObjectID))
|
|
return
|
|
|
|
def HandleJoinWorld(Server : GameServer, data : bytes, address : Address):
|
|
stream = ReadStream(data)
|
|
ObjectID = stream.read(c_longlong)
|
|
player : Character = Server.Game.getCharacterByObjectID(ObjectID)
|
|
if(player.Zone == ZoneID.NoZone.value):
|
|
player.Zone = ZoneID.VentureExplorer.value
|
|
SpawnAtDefault = False
|
|
if(player.ObjectConfig["Position"] == Vector3(0,0,0)):
|
|
SpawnAtDefault = True
|
|
LoadWorld(Server, player, player.Zone, address, SpawnAtDefault=SpawnAtDefault)
|
|
|
|
def LoadWorld(Server : GameServer, Player : Character, zoneID : ZoneID, address : Address, SpawnAtDefault : bool = False):
|
|
packet = WriteStream()
|
|
print("Sending Player {} to Zone {}".format(Player.ObjectConfig["ObjectID"], zoneID))
|
|
writeHeader(packet, PacketHeader.WorldInfo)
|
|
zone : Zone = Server.Game.getZoneByID(zoneID)
|
|
packet.write(c_uint16(zoneID))
|
|
packet.write(c_uint16(0))#MapInstance
|
|
packet.write(c_uint16(0))#MapClone
|
|
checksum = getZoneChecksum(zoneID)
|
|
for byte in checksum:
|
|
packet.write(c_ubyte(byte))
|
|
if(SpawnAtDefault):
|
|
packet.write(c_float(zone.SpawnLocation.X))
|
|
packet.write(c_float(zone.SpawnLocation.Y))
|
|
packet.write(c_float(zone.SpawnLocation.Z))
|
|
else:
|
|
packet.write(c_float(Player.ObjectConfig["Position"].X))
|
|
packet.write(c_float(Player.ObjectConfig["Position"].Y))
|
|
packet.write(c_float(Player.ObjectConfig["Position"].Z))
|
|
if(zone.ActivityWorld):
|
|
packet.write(c_ulong(4))
|
|
else:
|
|
packet.write(c_ulong(0))
|
|
session : Session = Server.Game.getSessionByAddress(address)
|
|
session.ObjectID = Player.ObjectConfig["ObjectID"]
|
|
Player.Zone = zoneID
|
|
Server.send(packet, address)
|
|
|
|
def HandleDetailedLoad(Server : GameServer, data : bytes, address : Address):
|
|
packet = WriteStream()
|
|
session : Session = Server.Game.getSessionByAddress(address)
|
|
player : Character = Server.Game.getCharacterByObjectID(session.ObjectID)
|
|
ldf = LDF()
|
|
ldf.registerKey("levelid", player.Zone, 1)
|
|
ldf.registerKey("objid", player.ObjectConfig["ObjectID"], 9)
|
|
ldf.registerKey("template", player.ObjectConfig["LOT"], 1)
|
|
ldf.registerKey("name", player.ObjectConfig["Name"], 0)
|
|
|
|
root = ElementTree.Element("obj")
|
|
root.set("v", "1")
|
|
buff = ElementTree.SubElement(root, "buff")
|
|
skill = ElementTree.SubElement(root, "skill")
|
|
|
|
inv = ElementTree.SubElement(root, "inv")
|
|
bag = ElementTree.SubElement(inv, "bag")
|
|
bagInfo = ElementTree.SubElement(bag, "b")
|
|
bagInfo.set("t", "0")
|
|
bagInfo.set("m", str(player.Inventory.Space))
|
|
items = ElementTree.SubElement(inv, "items")
|
|
itemIn = ElementTree.SubElement(items, "in")
|
|
for item in player.Inventory.InventoryList:
|
|
i = ElementTree.SubElement(itemIn, "i")
|
|
i.set("l", str(item["LOT"]))
|
|
i.set("id", str(item["ObjectID"]))
|
|
i.set("s", str(item["Slot"]))
|
|
i.set("c", str(item["Quantity"]))
|
|
i.set("b", str(int(item["Linked"])))
|
|
i.set("eq", str(int(item["Equipped"])))
|
|
|
|
mf = ElementTree.SubElement(root, "mf")
|
|
char = ElementTree.SubElement(root, "char")
|
|
char.set("cc", str(player.Currency))
|
|
char.set("ls", str(player.UniverseScore))
|
|
lvl = ElementTree.SubElement(root, "lvl")
|
|
lvl.set("l", str(player.Level))
|
|
|
|
pets = ElementTree.SubElement(root, "pet")
|
|
|
|
mis = ElementTree.SubElement(root, "mis")
|
|
done = ElementTree.SubElement(mis, "done")
|
|
for mission in player.CompletedMissionIDs:
|
|
m = ElementTree.SubElement(done, "m")
|
|
m.set("id", str(mission))
|
|
m.set("cct", "1")
|
|
m.set("cts", "0")
|
|
cur = ElementTree.SubElement(mis, "cur")
|
|
for mission in player.CurrentMissions:
|
|
m = ElementTree.SubElement(cur, "m")
|
|
m.set("id", str(mission.MissionID))
|
|
sv = ElementTree.SubElement(m, "sv")
|
|
sv.set("v", str(mission.Progress))
|
|
|
|
ldf.registerKey("xmlData", root, 13)
|
|
|
|
buffer = WriteStream()
|
|
ldf.writeLDF(buffer)
|
|
bufferLen = len(copy.deepcopy(buffer).__bytes__())
|
|
|
|
#print(from_ldf(ReadStream(copy.deepcopy(buffer).__bytes__())))
|
|
|
|
packet = WriteStream()
|
|
writeHeader(packet, PacketHeader.DetailedUserInfo)
|
|
packet.write(c_ulong(bufferLen+5))
|
|
packet.write(c_bool(False))
|
|
packet.write(buffer.__bytes__())
|
|
|
|
Server.send(packet, address)
|
|
print("Sent Detailed User Info to Player {}".format(player.ObjectConfig["ObjectID"]))
|
|
|
|
|
|
def SendCreationResponse(Server : GameServer, address : Address, Response : MinifigureCreationResponse):
|
|
packet = WriteStream()
|
|
writeHeader(packet, PacketHeader.MinifigureCreationResponse)
|
|
packet.write(c_uint8(Response.value))#Just going to leave it at success for now
|
|
Server.send(packet, address) |