mirror of
https://github.com/edubart/otclient.git
synced 2025-10-15 03:54:54 +02:00
More multiprotocol support
This commit is contained in:
@@ -92,7 +92,7 @@ end
|
||||
local function onLoginWait(message, time)
|
||||
CharacterList.destroyLoadBox()
|
||||
|
||||
waitingWindow = g_ui.loadUI('waitinglist.otui')
|
||||
waitingWindow = g_ui.displayUI('waitinglist.otui')
|
||||
|
||||
local label = waitingWindow:getChildById('infoLabel')
|
||||
label:setText(message)
|
||||
|
@@ -168,7 +168,8 @@ function EnterGame.doLogin()
|
||||
end })
|
||||
|
||||
g_game.chooseRsa(G.host)
|
||||
g_game.setProtocolVersion(protocol)
|
||||
g_game.setClientVersion(protocol)
|
||||
modules.game_tibiafiles.load()
|
||||
protocolLogin:login(G.host, G.port, G.account, G.password)
|
||||
end
|
||||
|
||||
|
@@ -72,7 +72,14 @@ function connect(object, arg1, arg2, arg3)
|
||||
end
|
||||
end
|
||||
|
||||
function disconnect(object, signalsAndSlots)
|
||||
function disconnect(object, arg1, arg2)
|
||||
local signalsAndSlots
|
||||
if type(arg1) == 'string' then
|
||||
signalsAndSlots = { [arg1] = arg2 }
|
||||
else
|
||||
signalsAndSlots = arg1
|
||||
end
|
||||
|
||||
for signal,slot in pairs(signalsAndSlots) do
|
||||
if not object[signal] then
|
||||
elseif type(object[signal]) == 'function' then
|
||||
@@ -231,11 +238,19 @@ end
|
||||
|
||||
function signalcall(param, ...)
|
||||
if type(param) == 'function' then
|
||||
return param(...)
|
||||
local status, ret = pcall(param, ...)
|
||||
if status then
|
||||
return ret
|
||||
else
|
||||
perror(ret)
|
||||
end
|
||||
elseif type(param) == 'table' then
|
||||
for k,v in pairs(param) do
|
||||
if v(...) then
|
||||
return true
|
||||
local status, ret = pcall(v, ...)
|
||||
if status then
|
||||
if ret then return true end
|
||||
else
|
||||
perror(ret)
|
||||
end
|
||||
end
|
||||
elseif func ~= nil then
|
||||
|
@@ -91,7 +91,7 @@ end
|
||||
function addAllCreatures()
|
||||
local spectators = {}
|
||||
local player = g_game.getLocalPlayer()
|
||||
if player then
|
||||
if g_game.isOnline() then
|
||||
creatures = g_map.getSpectators(player:getPosition(), false)
|
||||
for i, creature in ipairs(creatures) do
|
||||
if creature ~= player and doCreatureFitFilters(creature) then
|
||||
@@ -129,7 +129,7 @@ end
|
||||
|
||||
function checkCreatures(forceRecheck)
|
||||
local player = g_game.getLocalPlayer()
|
||||
if player then
|
||||
if g_game.isOnline() then
|
||||
local spectators = {}
|
||||
|
||||
-- reloading list of spectators
|
||||
|
@@ -135,10 +135,6 @@ function toggle()
|
||||
end
|
||||
end
|
||||
|
||||
function onMiniWindowClose()
|
||||
combatControlsButton:setOn(false)
|
||||
end
|
||||
|
||||
function onSetFightMode(self, selectedFightButton)
|
||||
if selectedFightButton == nil then return end
|
||||
local buttonId = selectedFightButton:getId()
|
||||
|
@@ -27,7 +27,6 @@ MiniWindow
|
||||
!text: tr('Combat Controls')
|
||||
icon: combatcontrols.png
|
||||
height: 48
|
||||
@onClose: CombatControls.onMiniWindowClose()
|
||||
&save: true
|
||||
|
||||
MiniWindowContents
|
||||
|
@@ -37,14 +37,14 @@ function clean()
|
||||
end
|
||||
end
|
||||
|
||||
local function refreshContainerItems(container)
|
||||
function refreshContainerItems(container)
|
||||
for slot=0,container:getCapacity()-1 do
|
||||
local itemWidget = container.itemsPanel:getChildById('item' .. slot)
|
||||
itemWidget:setItem(container:getItem(slot))
|
||||
end
|
||||
end
|
||||
|
||||
local function onContainerOpen(container, previousContainer)
|
||||
function onContainerOpen(container, previousContainer)
|
||||
local containerWindow
|
||||
if previousContainer then
|
||||
containerWindow = previousContainer.window
|
||||
|
@@ -2,7 +2,7 @@ Icons = {}
|
||||
Icons[1] = { tooltip = tr('You are poisoned'), path = '/game_healthinfo/icons/poisoned.png', id = 'condition_poisoned' }
|
||||
Icons[2] = { tooltip = tr('You are burning'), path = '/game_healthinfo/icons/burning.png', id = 'condition_burning' }
|
||||
Icons[4] = { tooltip = tr('You are electrified'), path = '/game_healthinfo/icons/electrified.png', id = 'condition_electrified' }
|
||||
Icons[8] = { tooltip = tr('You are freezing'), path = '/game_healthinfo/icons/drunk.png', id = 'condition_drunk' }
|
||||
Icons[8] = { tooltip = tr('You are drunk'), path = '/game_healthinfo/icons/drunk.png', id = 'condition_drunk' }
|
||||
Icons[16] = { tooltip = tr('You are protected by a magic shield'), path = '/game_healthinfo/icons/magic_shield.png', id = 'condition_magic_shield' }
|
||||
Icons[32] = { tooltip = tr('You are paralysed'), path = '/game_healthinfo/icons/slowed.png', id = 'condition_slowed' }
|
||||
Icons[64] = { tooltip = tr('You are hasted'), path = '/game_healthinfo/icons/haste.png', id = 'condition_haste' }
|
||||
|
@@ -238,6 +238,7 @@ function startTradeWith(thing)
|
||||
end
|
||||
|
||||
function createThingMenu(menuPosition, lookThing, useThing, creatureThing)
|
||||
if not g_game.isOnline() then return end
|
||||
local menu = g_ui.createWidget('PopupMenu')
|
||||
|
||||
if lookThing then
|
||||
@@ -297,52 +298,50 @@ function createThingMenu(menuPosition, lookThing, useThing, creatureThing)
|
||||
|
||||
else
|
||||
local localPlayer = g_game.getLocalPlayer()
|
||||
if localPlayer then
|
||||
if g_game.getAttackingCreature() ~= creatureThing then
|
||||
menu:addOption(tr('Attack'), function() g_game.attack(creatureThing) end)
|
||||
else
|
||||
menu:addOption(tr('Stop Attack'), function() g_game.cancelAttack() end)
|
||||
if g_game.getAttackingCreature() ~= creatureThing then
|
||||
menu:addOption(tr('Attack'), function() g_game.attack(creatureThing) end)
|
||||
else
|
||||
menu:addOption(tr('Stop Attack'), function() g_game.cancelAttack() end)
|
||||
end
|
||||
|
||||
if g_game.getFollowingCreature() ~= creatureThing then
|
||||
menu:addOption(tr('Follow'), function() g_game.follow(creatureThing) end)
|
||||
else
|
||||
menu:addOption(tr('Stop Follow'), function() g_game.cancelFollow() end)
|
||||
end
|
||||
|
||||
if creatureThing:asPlayer() then
|
||||
menu:addSeparator()
|
||||
local creatureName = creatureThing:getName()
|
||||
menu:addOption(tr('Message to %s', creatureName), function() g_game.openPrivateChannel(creatureName) end)
|
||||
if modules.game_console.getOwnPrivateTab() then
|
||||
menu:addOption(tr('Invite to private chat'), function() g_game.inviteToOwnChannel(creatureName) end)
|
||||
menu:addOption(tr('Exclude from private chat'), function() g_game.excludeFromOwnChannel(creatureName) end) -- [TODO] must be removed after message's popup labels been implemented
|
||||
end
|
||||
if (not Player:hasVip(creatureName)) then
|
||||
menu:addOption(tr('Add to VIP list'), function() g_game.addVip(creatureName) end)
|
||||
end
|
||||
|
||||
if g_game.getFollowingCreature() ~= creatureThing then
|
||||
menu:addOption(tr('Follow'), function() g_game.follow(creatureThing) end)
|
||||
else
|
||||
menu:addOption(tr('Stop Follow'), function() g_game.cancelFollow() end)
|
||||
end
|
||||
local localPlayerShield = localPlayer:asCreature():getShield()
|
||||
local creatureShield = creatureThing:getShield()
|
||||
|
||||
if creatureThing:asPlayer() then
|
||||
menu:addSeparator()
|
||||
local creatureName = creatureThing:getName()
|
||||
menu:addOption(tr('Message to %s', creatureName), function() g_game.openPrivateChannel(creatureName) end)
|
||||
if modules.game_console.getOwnPrivateTab() then
|
||||
menu:addOption(tr('Invite to private chat'), function() g_game.inviteToOwnChannel(creatureName) end)
|
||||
menu:addOption(tr('Exclude from private chat'), function() g_game.excludeFromOwnChannel(creatureName) end) -- [TODO] must be removed after message's popup labels been implemented
|
||||
if localPlayerShield == ShieldNone or localPlayerShield == ShieldWhiteBlue then
|
||||
if creatureShield == ShieldWhiteYellow then
|
||||
menu:addOption(tr('Join %s\'s Party', creatureThing:getName()), function() g_game.partyJoin(creatureThing:getId()) end)
|
||||
else
|
||||
menu:addOption(tr('Invite to Party'), function() g_game.partyInvite(creatureThing:getId()) end)
|
||||
end
|
||||
if (not Player:hasVip(creatureName)) then
|
||||
menu:addOption(tr('Add to VIP list'), function() g_game.addVip(creatureName) end)
|
||||
elseif localPlayerShield == ShieldWhiteYellow then
|
||||
if creatureShield == ShieldWhiteBlue then
|
||||
menu:addOption(tr('Revoke %s\'s Invitation', creatureThing:getName()), function() g_game.partyRevokeInvitation(creatureThing:getId()) end)
|
||||
end
|
||||
|
||||
local localPlayerShield = localPlayer:asCreature():getShield()
|
||||
local creatureShield = creatureThing:getShield()
|
||||
|
||||
if localPlayerShield == ShieldNone or localPlayerShield == ShieldWhiteBlue then
|
||||
if creatureShield == ShieldWhiteYellow then
|
||||
menu:addOption(tr('Join %s\'s Party', creatureThing:getName()), function() g_game.partyJoin(creatureThing:getId()) end)
|
||||
else
|
||||
menu:addOption(tr('Invite to Party'), function() g_game.partyInvite(creatureThing:getId()) end)
|
||||
end
|
||||
elseif localPlayerShield == ShieldWhiteYellow then
|
||||
if creatureShield == ShieldWhiteBlue then
|
||||
menu:addOption(tr('Revoke %s\'s Invitation', creatureThing:getName()), function() g_game.partyRevokeInvitation(creatureThing:getId()) end)
|
||||
end
|
||||
elseif localPlayerShield == ShieldYellow or localPlayerShield == ShieldYellowSharedExp or localPlayerShield == ShieldYellowNoSharedExpBlink or localPlayerShield == ShieldYellowNoSharedExp then
|
||||
if creatureShield == ShieldWhiteBlue then
|
||||
menu:addOption(tr('Revoke %s\'s Invitation', creatureThing:getName()), function() g_game.partyRevokeInvitation(creatureThing:getId()) end)
|
||||
elseif creatureShield == ShieldBlue or creatureShield == ShieldBlueSharedExp or creatureShield == ShieldBlueNoSharedExpBlink or creatureShield == ShieldBlueNoSharedExp then
|
||||
menu:addOption(tr('Pass Leadership to %s', creatureThing:getName()), function() g_game.partyPassLeadership(creatureThing:getId()) end)
|
||||
else
|
||||
menu:addOption(tr('Invite to Party'), function() g_game.partyInvite(creatureThing:getId()) end)
|
||||
end
|
||||
elseif localPlayerShield == ShieldYellow or localPlayerShield == ShieldYellowSharedExp or localPlayerShield == ShieldYellowNoSharedExpBlink or localPlayerShield == ShieldYellowNoSharedExp then
|
||||
if creatureShield == ShieldWhiteBlue then
|
||||
menu:addOption(tr('Revoke %s\'s Invitation', creatureThing:getName()), function() g_game.partyRevokeInvitation(creatureThing:getId()) end)
|
||||
elseif creatureShield == ShieldBlue or creatureShield == ShieldBlueSharedExp or creatureShield == ShieldBlueNoSharedExpBlink or creatureShield == ShieldBlueNoSharedExp then
|
||||
menu:addOption(tr('Pass Leadership to %s', creatureThing:getName()), function() g_game.partyPassLeadership(creatureThing:getId()) end)
|
||||
else
|
||||
menu:addOption(tr('Invite to Party'), function() g_game.partyInvite(creatureThing:getId()) end)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@@ -43,7 +43,7 @@ end
|
||||
function refresh()
|
||||
local player = g_game.getLocalPlayer()
|
||||
for i=InventorySlotFirst,InventorySlotLast do
|
||||
if player then
|
||||
if g_game.isOnline() then
|
||||
onInventoryChange(player, i, player:getInventoryItem(i))
|
||||
else
|
||||
onInventoryChange(player, i, nil)
|
||||
@@ -67,8 +67,9 @@ end
|
||||
|
||||
-- hooked events
|
||||
function onInventoryChange(player, slot, item, oldItem)
|
||||
if slot >= InventorySlotPurse then return end
|
||||
local itemWidget = inventoryPanel:getChildById('slot' .. slot)
|
||||
if(item) then
|
||||
if item then
|
||||
itemWidget:setStyle('Item')
|
||||
itemWidget:setItem(item)
|
||||
else
|
||||
|
@@ -38,7 +38,7 @@ end
|
||||
local function parseMarketEnter(msg)
|
||||
local balance = msg:getU32()
|
||||
local vocation = -1
|
||||
if g_game.getProtocolVersion() < 950 then
|
||||
if g_game.getClientVersion() < 950 then
|
||||
vocation = msg:getU8() -- get vocation id
|
||||
end
|
||||
local offers = msg:getU8()
|
||||
@@ -74,7 +74,8 @@ local function parseMarketDetail(msg)
|
||||
end
|
||||
|
||||
local purchaseStats = {}
|
||||
if msg:getU8() == 0x01 then
|
||||
local count = msg:getU8()
|
||||
for i=1,count do
|
||||
local transactions = msg:getU32() -- transaction count
|
||||
local totalPrice = msg:getU32() -- total price
|
||||
local highestPrice = msg:getU32() -- highest price
|
||||
@@ -84,7 +85,8 @@ local function parseMarketDetail(msg)
|
||||
end
|
||||
|
||||
local saleStats = {}
|
||||
if msg:getU8() == 0x01 then
|
||||
count = msg:getU8()
|
||||
for i=1,count do
|
||||
local transactions = msg:getU32() -- transaction count
|
||||
local totalPrice = msg:getU32() -- total price
|
||||
local highestPrice = msg:getU32() -- highest price
|
||||
|
@@ -67,6 +67,7 @@ function loadReasons()
|
||||
local actions = g_game.getGMActions()
|
||||
for reason, actionFlags in pairs(actions) do
|
||||
local label = g_ui.createWidget('RVListLabel', reasonsTextList)
|
||||
label.onFocusChange = onSelectReason
|
||||
label:setText(rvreasons[reason])
|
||||
label.reasonId = reason
|
||||
label.actionFlags = actionFlags
|
||||
|
@@ -2,7 +2,6 @@ RVListLabel < Label
|
||||
background-color: alpha
|
||||
text-offset: 2 0
|
||||
focusable: true
|
||||
@onFocusChange: function (self, focused) RuleViolation.onSelectReason(self, focused) end
|
||||
|
||||
$focus:
|
||||
background-color: #ffffff22
|
||||
@@ -109,7 +108,7 @@ MainWindow
|
||||
width: 64
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
@onClick: RuleViolation.hide()
|
||||
@onClick: hide()
|
||||
|
||||
Button
|
||||
!text: tr('Ok')
|
||||
@@ -117,4 +116,4 @@ MainWindow
|
||||
margin-right: 5
|
||||
anchors.right: prev.left
|
||||
anchors.bottom: parent.bottom
|
||||
@onClick: RuleViolation.report()
|
||||
@onClick: report()
|
@@ -47,7 +47,7 @@ end
|
||||
function parseTextMessage(msg)
|
||||
local msgtype = msg:getU8()
|
||||
local text = msg:getString()
|
||||
msgtype = getMessageTypes(g_game.getProtocolVersion())[msgtype]
|
||||
msgtype = getMessageTypes(g_game.getClientVersion())[msgtype]
|
||||
signalcall(g_game.onTextMessage, msgtype, text)
|
||||
end
|
||||
|
||||
|
@@ -1,11 +1,17 @@
|
||||
function init()
|
||||
if not g_things.loadDat('/game_tibiafiles/Tibia.dat') then
|
||||
fatal(tr("Unable to load dat file, please place a valid Tibia dat in modules/game_tibiafiles/Tibia.dat"))
|
||||
end
|
||||
if not g_sprites.loadSpr('/game_tibiafiles/Tibia.spr') then
|
||||
fatal(tr("Unable to load spr file, please place a valid Tibia spr in modules/game_tibiafiles/Tibia.spr"))
|
||||
if g_game.getClientVersion() ~= 0 then
|
||||
load()
|
||||
end
|
||||
end
|
||||
|
||||
function terminate()
|
||||
function load()
|
||||
local version = g_game.getClientVersion()
|
||||
local datPath = resolvepath(version .. '/Tibia.dat')
|
||||
local sprPath = resolvepath(version .. '/Tibia.spr')
|
||||
if not g_things.loadDat(datPath) then
|
||||
fatal(tr("Unable to load dat file, please place a valid dat in '%s'", datPath))
|
||||
end
|
||||
if not g_sprites.loadSpr(sprPath) then
|
||||
fatal(tr("Unable to load spr file, please place a valid spr in '%s'", sprPath))
|
||||
end
|
||||
end
|
||||
|
@@ -71,6 +71,9 @@ CIPSOFT_RSA = "1321277432058722840622950990822933849527763264961655079678763618"
|
||||
"2907336840325241747827401343576296990629870233111328210165697754" ..
|
||||
"88792221429527047321331896351555606801473202394175817"
|
||||
|
||||
-- set to the latest Tibia.pic signature to make otclient compatible with official tibia
|
||||
PIC_SIGNATURE = 1337606793
|
||||
|
||||
OsTypes = {
|
||||
Linux = 1,
|
||||
Windows = 2,
|
||||
|
@@ -11,6 +11,7 @@ InventorySlotLeg = 7
|
||||
InventorySlotFeet = 8
|
||||
InventorySlotFinger = 9
|
||||
InventorySlotAmmo = 10
|
||||
InventorySlotPurse = 11
|
||||
|
||||
InventorySlotFirst = 1
|
||||
InventorySlotLast = 10
|
||||
|
@@ -1,89 +1,11 @@
|
||||
-- @docclass
|
||||
ProtocolLogin = extends(Protocol)
|
||||
|
||||
-- set to the latest Tibia.pic signature to make otclient compatible with official tibia
|
||||
local PIC_SIGNATURE = 1337606793
|
||||
|
||||
LoginServerError = 10
|
||||
LoginServerMotd = 20
|
||||
LoginServerUpdateNeeded = 30
|
||||
LoginServerCharacterList = 100
|
||||
|
||||
|
||||
-- private functions
|
||||
local function sendLoginPacket(protocol)
|
||||
local msg = OutputMessage.create()
|
||||
msg:addU8(ClientOpcodes.ClientEnterAccount)
|
||||
msg:addU16(g_game.getOsType())
|
||||
msg:addU16(g_game.getProtocolVersion())
|
||||
|
||||
msg:addU32(g_things.getDatSignature())
|
||||
msg:addU32(g_sprites.getSprSignature())
|
||||
msg:addU32(PIC_SIGNATURE)
|
||||
|
||||
local paddingBytes = 128
|
||||
msg:addU8(0) -- first RSA byte must be 0
|
||||
paddingBytes = paddingBytes - 1
|
||||
|
||||
-- xtea key
|
||||
protocol:generateXteaKey()
|
||||
local xteaKey = protocol:getXteaKey()
|
||||
msg:addU32(xteaKey[1])
|
||||
msg:addU32(xteaKey[2])
|
||||
msg:addU32(xteaKey[3])
|
||||
msg:addU32(xteaKey[4])
|
||||
paddingBytes = paddingBytes - 16
|
||||
|
||||
if g_game.getFeature(GameProtocolChecksum) then
|
||||
protocol:enableChecksum()
|
||||
end
|
||||
|
||||
if g_game.getFeature(GameAccountNames) then
|
||||
msg:addString(protocol.accountName)
|
||||
msg:addString(protocol.accountPassword)
|
||||
paddingBytes = paddingBytes - (4 + string.len(protocol.accountName) + string.len(protocol.accountPassword))
|
||||
else
|
||||
msg:addU32(tonumber(protocol.accountName))
|
||||
msg:addString(protocol.accountPassword)
|
||||
paddingBytes = paddingBytes - (6 + string.len(protocol.accountPassword))
|
||||
end
|
||||
|
||||
msg:addPaddingBytes(paddingBytes, 0)
|
||||
msg:encryptRsa(128, g_game.getRsa())
|
||||
|
||||
protocol:send(msg)
|
||||
protocol:enableXteaEncryption()
|
||||
protocol:recv()
|
||||
end
|
||||
|
||||
-- events
|
||||
function ProtocolLogin:onConnect()
|
||||
self:connectCallback(self)
|
||||
end
|
||||
|
||||
function ProtocolLogin:onRecv(msg)
|
||||
while not msg:eof() do
|
||||
local opcode = msg:getU8()
|
||||
if opcode == LoginServerError then
|
||||
self:parseError(msg)
|
||||
elseif opcode == LoginServerMotd then
|
||||
self:parseMotd(msg)
|
||||
elseif opcode == LoginServerUpdateNeeded then
|
||||
signalcall(self.onError, self, tr("Client needs update."))
|
||||
elseif opcode == LoginServerCharacterList then
|
||||
self:parseCharacterList(msg)
|
||||
else
|
||||
self:parseOpcode(opcode, msg)
|
||||
end
|
||||
end
|
||||
self:disconnect()
|
||||
end
|
||||
|
||||
-- public functions
|
||||
function ProtocolLogin.create()
|
||||
return ProtocolLogin.internalCreate()
|
||||
end
|
||||
|
||||
function ProtocolLogin:login(host, port, accountName, accountPassword)
|
||||
if string.len(accountName) == 0 or string.len(accountPassword) == 0 then
|
||||
signalcall(self.onError, self, tr("You must enter an account name and password."))
|
||||
@@ -105,6 +27,73 @@ function ProtocolLogin:cancelLogin()
|
||||
self:disconnect()
|
||||
end
|
||||
|
||||
function ProtocolLogin:sendLoginPacket()
|
||||
local msg = OutputMessage.create()
|
||||
msg:addU8(ClientOpcodes.ClientEnterAccount)
|
||||
msg:addU16(g_game.getOsType())
|
||||
msg:addU16(g_game.getClientVersion())
|
||||
|
||||
msg:addU32(g_things.getDatSignature())
|
||||
msg:addU32(g_sprites.getSprSignature())
|
||||
msg:addU32(PIC_SIGNATURE)
|
||||
|
||||
local paddingBytes = 128
|
||||
msg:addU8(0) -- first RSA byte must be 0
|
||||
paddingBytes = paddingBytes - 1
|
||||
|
||||
-- xtea key
|
||||
self:generateXteaKey()
|
||||
local xteaKey = self:getXteaKey()
|
||||
msg:addU32(xteaKey[1])
|
||||
msg:addU32(xteaKey[2])
|
||||
msg:addU32(xteaKey[3])
|
||||
msg:addU32(xteaKey[4])
|
||||
paddingBytes = paddingBytes - 16
|
||||
|
||||
if g_game.getFeature(GameProtocolChecksum) then
|
||||
self:enableChecksum()
|
||||
end
|
||||
|
||||
if g_game.getFeature(GameAccountNames) then
|
||||
msg:addString(self.accountName)
|
||||
msg:addString(self.accountPassword)
|
||||
paddingBytes = paddingBytes - (4 + string.len(self.accountName) + string.len(self.accountPassword))
|
||||
else
|
||||
msg:addU32(tonumber(self.accountName))
|
||||
msg:addString(self.accountPassword)
|
||||
paddingBytes = paddingBytes - (6 + string.len(self.accountPassword))
|
||||
end
|
||||
|
||||
msg:addPaddingBytes(paddingBytes, 0)
|
||||
msg:encryptRsa(128, g_game.getRsa())
|
||||
|
||||
self:send(msg)
|
||||
self:enableXteaEncryption()
|
||||
self:recv()
|
||||
end
|
||||
|
||||
function ProtocolLogin:onConnect()
|
||||
self:sendLoginPacket()
|
||||
end
|
||||
|
||||
function ProtocolLogin:onRecv(msg)
|
||||
while not msg:eof() do
|
||||
local opcode = msg:getU8()
|
||||
if opcode == LoginServerError then
|
||||
self:parseError(msg)
|
||||
elseif opcode == LoginServerMotd then
|
||||
self:parseMotd(msg)
|
||||
elseif opcode == LoginServerUpdateNeeded then
|
||||
signalcall(self.onError, self, tr("Client needs update."))
|
||||
elseif opcode == LoginServerCharacterList then
|
||||
self:parseCharacterList(msg)
|
||||
else
|
||||
self:parseOpcode(opcode, msg)
|
||||
end
|
||||
end
|
||||
self:disconnect()
|
||||
end
|
||||
|
||||
function ProtocolLogin:parseError(msg)
|
||||
local errorMessage = msg:getString()
|
||||
signalcall(self.onError, self, errorMessage)
|
||||
|
Reference in New Issue
Block a user