• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

C++ Alpha Proxy - just help me ;/

OTAmator

Member
Joined
May 4, 2016
Messages
85
Reaction score
23
Hi,

I'm having trouble getting the Alpha Proxy to work. I have two VPS servers available for testing. I'm not sharing the real IP addresses of my VPSs, so for the sake of this thread, let's assume the IPs are as follows:
1. vps ip: 1.1.1.1 (backend with tfs)
2. vps ip: 2.2.2.2 (proxy server)

TFS i use nekiro TFS-1.5-Downgrade version 8.0:
I have applied tfs changes for proxy from Alpha Proxy Guids from attached proxy1.4.patch file:


First VPS tfs config:
Code:
ip = "127.0.0.1" -- important, do not change
statusIP = "2.2.2.2" -- set this to your closest forward proxy server IP
bindOnlyGlobalAddress = true -- important, do not change
loginProtocolPort = 7171
gameProtocolPort = 7172
statusProtocolPort = 7171


Second VPS HAProxy configuration:
LUA:
global
        chroot /var/lib/haproxy
        stats socket /run/haproxy/admin.sock mode 660 level admin
        stats timeout 30s
        user haproxy
        group haproxy
        daemon

defaults
        timeout connect 4s
        timeout client 50s
        timeout server 50s

# login connections
listen l1
        bind 0.0.0.0:7101
        mode tcp
        server srv1 1.1.1.1:7101 send-proxy-v2
# game connections
listen l2
        bind 0.0.0.0:7201
        mode tcp
        server srv2 1.1.1.1:7201 send-proxy-v2
# status connections
listen l3
        bind 0.0.0.0:7301
        mode tcp
        server srv3 1.1.1.1:7301 send-proxy-v2

First VPS Reverse Proxy Configuration:
Code:
global
        chroot /var/lib/haproxy
        stats socket /run/haproxy/admin.sock mode 660 level admin
        stats timeout 30s
        user haproxy
        group haproxy
        daemon

defaults
        timeout connect 4s
        timeout client 50s
        timeout server 50s
  
# login connections
listen l1
        bind 0.0.0.0:7101 accept-proxy
        mode tcp
        server srv1 127.0.0.1:7171 send-proxy-v2
# status connections
listen l2
        bind 0.0.0.0:7301 accept-proxy
        mode tcp
        server srv1 127.0.0.1:7171 send-proxy-v2

Alpha proxy on first VPS is running on port 7201:
Code:
Starting proxy server on port 7201 with a maximum of 10 connections per IP allowed
[Server] open : 7201

Added database for proxy to tfs on First VPS:
Code:
INSERT INTO `proxies` (`id`, `host`, `port`, `priority`, `disabled`) VALUES
(5, '2.2.2.2', 7201, 0, 0);

In OTClient added in init.lua:
g_proxy.addProxy('2.2.2.2', 7201, 0)

Results:
I use this client:

With using Gesior's modifications from:

client debug proxy:
1745658293257.webp
client logs:
Connecting to: 127.0.0.1:7171
[Proxy 2.2.2.2] onHeader error The network connection was interrupted by the local system.

I also tested without gesior modifications (just on master branch) and got same results. I ended up with the same results. Can anyone help?
 
Solution
It's hard to review all configuration and all possible network/software problems on forum. There are too many things that can go wrong.
Add me on Discord: gesior.pl
I will try to help you with config and then we will post on forum what was wrong and how we fixed it.
Post automatically merged:

There was only 1 thing wrong. Code to read IP of proxy user was added in wrong place. It must be before checking, if packet is too long. Proxy packet size (read from first 2 bytes of packet) is always too big and it blocks rest of code.

I could not connect with clean OTCv8 client, because key.pem was replaced with custom RSA key, but IDK if it was related to OTAmator problems. He is offline now, so I can't confirm, if he...
client debug proxy:
It shows ping, so communication client <-> alpha server works.
It cannot connect from alpha server to OTS for some reason. Maybe changes in your engine are in wrong places or some of them are missing.
You can replace Alpha server with this (it's compiled Kondra proxy):
chmod +x proxy_server_x64 and ./proxy_server_x64 7201 to run.
It's version of proxy that does not pass IP of player to server and it does not require any changes in server code, so it should work with clean Nekiro sources.
 
Your backend & proxy configuration look to be correct, and we can be confident in that as the proxy debug information shows the connection is active. The issue must be with the client or TFS source changes.

You may find it easier to step through the source changes required by viewing my tfs fork that I used to generate the patch file: proxy1.4 · thatmichaelguy/forgottenserver@034c0d2 (https://github.com/thatmichaelguy/forgottenserver/commit/034c0d229049787cd261525642815da11286ad59)

As for the client, the version you linked is outdated, use this instead: GitHub - OTAcademy/otclientv8: Mirror of official OTClientV8 (https://github.com/OTAcademy/otclientv8)
Don't add g_proxy.addProxy('2.2.2.2', 7201, 0) to your init.lua - it isn't required in this configuration as that information is given by the loginserver after successful login.
Also don't try to make any additional client source changes, you don't need to, those changes you linked from Gesior are for a different client version.
 
Your backend & proxy configuration look to be correct, and we can be confident in that as the proxy debug information shows the connection is active. The issue must be with the client or TFS source changes.

You may find it easier to step through the source changes required by viewing my tfs fork that I used to generate the patch file: proxy1.4 · thatmichaelguy/forgottenserver@034c0d2 (https://github.com/thatmichaelguy/forgottenserver/commit/034c0d229049787cd261525642815da11286ad59)

As for the client, the version you linked is outdated, use this instead: GitHub - OTAcademy/otclientv8: Mirror of official OTClientV8 (https://github.com/OTAcademy/otclientv8)
Don't add g_proxy.addProxy('2.2.2.2', 7201, 0) to your init.lua - it isn't required in this configuration as that information is given by the loginserver after successful login.
Also don't try to make any additional client source changes, you don't need to, those changes you linked from Gesior are for a different client version.
The TFS changes are identical to the ones in the commit you linked

I'm currently using the OtClient from OTAcademy.
I added the following to init.lua:

LUA:
g_proxy.addProxy('2.2.2.2', 7201, 0)

Unfortunately, the Alpha proxy throws an error for me.

[Server] new connection
[Proxy 0] onProxyHeader: Connections per IP: 0, m_ip = {hidden_ip_1} m_proxy_ip = {hidden_ip_2}
[Proxy 0] onProxyHeader: Continuing with connection, connections from IP now: 1, m_ip = {hidden_ip_1}, m_proxy_ip = {hidden_ip_2}
[Proxy 0] onHeader error: Connection reset by peer
[Proxy 0] terminate connection from m_ip = {hidden_ip_1}, m_proxy_ip = {hidden_ip_2}
[Proxy 0] Proxy::~Proxy(): m_ip = {hidden_ip_1}, m_proxy_ip = {hidden_ip_2}
[Proxy 0] Proxy::~Proxy(): connection count from {hidden_ip_1} reached 0, erasing map key from g_connectionsPerIp
[Proxy 0] Proxy::~Proxy(): reducing connection count by 1, new count: 0

in client im connecting to:
LUA:
127.0.0.1:7171:800
 
You're mixing instructions from my guide and from Gesior - his method differs in some ways, and while there are some potential advantages worth adopting, for now just follow my guide until you have a working solution and then you can deviate from there:

  • Remove g_proxy.addProxy('2.2.2.2', 7201, 0) from init.lua
  • Change 127.0.0.1:7171:800 to 2.2.2.2:7101:800 (remember to change it to your forward proxy IP)
 
@Michael Orsino

We're making progress. I can now see the character list.
1746463606150.webp

but on login into the game i got ERROR 2
1746463624346.webp

alpha proxy debug log:

LUA:
[Proxy 7172] creating new session: 434469152
[Session 434469152] start, port: 7172
[Session 434469152] addProxy
[Session 434469152] connected to remote server
[Session 434469152] onProxyPacket, id: 1 (1) last: 0 (1) size: 135
[Session 434469152] onHeader error: End of file
[Session 434469152] terminate
[Proxy 7172] sendSessionEnd: 434469152
[Proxy 7172] sendSessionEnd: 434469152

What else could be wrong that's preventing me from logging into the game?
 
there is changes from the original for sure so please send latest init.lua + latest debug window from otcv8, maybe haproxy from main server and 1 proxy server (hide your ips)
 
@El Bringy
Hello,
debug window? I don't have a debug window for the proxy. @Michael Orsino said that changes to the OTClient are unnecessary

In OTClient console there is
LUA:
Connecting to: 2.2.2.2:7101
Connecting to: 2.2.2.2:7101
Login to 127.0.0.1:7172
Login to 127.0.0.1:7172

I have added some couts to alpha proxy. May it help to you:

Code:
[Proxy 7172] creating new session: 3810391268
[Session 3810391268] start, port: 7172
[Session 3810391268] addProxy
[Session 3810391268] connected to remote server
[Session 3810391268] onProxyPacket, id: 1 (1) last: 0 (1) size: 135
[Session 3810391268] Buffer dump (first 32 bytes): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[Session 3810391268] onHeader error: End of file
[Session 3810391268] terminate
[Proxy 7172] sendSessionEnd: 3810391268
[Proxy 7172] sendSessionEnd: 3810391268
[Proxy 7172] creating new session: 2817966888
[Session 2817966888] start, port: 7172
[Session 2817966888] addProxy
[Session 2817966888] onProxyPacket, id: 1 (1) last: 0 (1) size: 135
[Session 2817966888] connected to remote server
[Session 2817966888] Buffer dump (first 32 bytes): 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 58 74 1e c3 ff 7f 00 00 00 00 00 00 00 00 00 00
[Session 2817966888] onHeader error: End of file
[Session 2817966888] terminate
[Proxy 7172] sendSessionEnd: 2817966888
[Proxy 7172] sendSessionEnd: 2817966888



init.lua
LUA:
-- CONFIG
APP_NAME = "otclientv8"  -- important, change it, it's name for config dir and files in appdata
APP_VERSION = 800       -- client version for updater and login to identify outdated client
DEFAULT_LAYOUT = "retro" -- on android it's forced to "mobile", check code bellow

-- If you don't use updater or other service, set it to updater = ""
Services = {
  website = "http://************", -- currently not used
  updater = "http://************/api/updater.php",
  stats = "",
  crash = "http://************/api/crash.php",
  feedback = "http://************/api/feedback.php",
  status = "http://************/api/status.php"
}

-- Servers accept http login url, websocket login url or ip:port:version
Servers = {
--[[  OTClientV8 = "http://************/api/login.php",
  OTClientV8proxy = "http://************/api/login.php?proxy=1",
  OTClientV8c = "************:7171:1099:25:30:80:90",
  OTClientV8Test = "http://************/api/login2.php",
  Evoulinia = "evolunia.net:7171:1098",
  GarneraTest = "garnera-global.net:7171:1100",
  LocalTestServ = "127.0.0.1:7171:1098:110:30:93"  ]]
  ALPHA = "2.2.2.2:7101:800",
}

--Server = "ws://************:3000/"
--Server = "ws://127.0.0.1:88/"
--USE_NEW_ENERGAME = true -- uses entergamev2 based on websockets instead of entergame
ALLOW_CUSTOM_SERVERS = true -- if true it shows option ANOTHER on server list

g_app.setName("OTCv8")
-- CONFIG END

-- print first terminal message
g_logger.info(os.date("== application started at %b %d %Y %X"))
g_logger.info(g_app.getName() .. ' ' .. g_app.getVersion() .. ' rev ' .. g_app.getBuildRevision() .. ' (' .. g_app.getBuildCommit() .. ') made by ' .. g_app.getAuthor() .. ' built on ' .. g_app.getBuildDate() .. ' for arch ' .. g_app.getBuildArch())

if not g_resources.directoryExists("/data") then
  g_logger.fatal("Data dir doesn't exist.")
end

if not g_resources.directoryExists("/modules") then
  g_logger.fatal("Modules dir doesn't exist.")
end

-- settings
g_configs.loadSettings("/config.otml")

-- set layout
local settings = g_configs.getSettings()
local layout = DEFAULT_LAYOUT
if g_app.isMobile() then
  layout = "mobile"
elseif settings:exists('layout') then
  layout = settings:getValue('layout')
end
g_resources.setLayout(layout)

-- load mods
g_modules.discoverModules()
g_modules.ensureModuleLoaded("corelib")

local function loadModules()
  -- libraries modules 0-99
  g_modules.autoLoadModules(99)
  g_modules.ensureModuleLoaded("gamelib")

  -- client modules 100-499
  g_modules.autoLoadModules(499)
  g_modules.ensureModuleLoaded("client")

  -- game modules 500-999
  g_modules.autoLoadModules(999)
  g_modules.ensureModuleLoaded("game_interface")

  -- mods 1000-9999
  g_modules.autoLoadModules(9999)
end

-- report crash
if type(Services.crash) == 'string' and Services.crash:len() > 4 and g_modules.getModule("crash_reporter") then
  g_modules.ensureModuleLoaded("crash_reporter")
end

-- run updater, must use data.zip
if type(Services.updater) == 'string' and Services.updater:len() > 4
  and g_resources.isLoadedFromArchive() and g_modules.getModule("updater") then
  g_modules.ensureModuleLoaded("updater")
  return Updater.init(loadModules)
end
loadModules()
 
the main issue is in entergame.lua it enforces connection to gameport sent from server side, send entergame.lua from client modules

trying to connect directly meanwhile the serverSide expects the HAProxy extra packets, to be able to login you need to direct connection to the proxy port onlogin and connection send entergame.lua i can show you the main issue location easily
 
under
LUA:
  ALPHA = "2.2.2.2:7101:800",
}

add this
Code:
for _, proxyIp in pairs(PROXY_IPS) do
     g_proxy.addProxy(proxyIp, 7101, 0)
end

and use this charlist.lua
i will assume that your gameServer is on <span>7201</span> because you never shared that with me based on the line you added in init.lua

try that characterlist.lua in modules/client_entergame
Code:
CharacterList = { }

-- private variables
local charactersWindow
local loadBox
local characterList
local errorBox
local waitingWindow
local autoReconnectButton
local updateWaitEvent
local resendWaitEvent
local loginEvent
local autoReconnectEvent
local lastLogout = 0

-- private functions
local function tryLogin(charInfo, tries)
  tries = tries or 1

  if tries > 50 then
    return
  end

  if g_game.isOnline() then
    if tries == 1 then
      g_game.safeLogout()
    end
    loginEvent = scheduleEvent(function() tryLogin(charInfo, tries+1) end, 100)
    return
  end

  CharacterList.hide()
  g_game.loginWorld(G.account, G.password, charInfo.worldName, charInfo.worldHost, 7201, charInfo.characterName, G.authenticatorToken, G.sessionKey)
  g_logger.info("Login to " .. charInfo.worldHost .. ": 7201")
  loadBox = displayCancelBox(tr('Please wait'), tr('Connecting to game server...'))
  connect(loadBox, { onCancel = function()
                                  loadBox = nil
                                  g_game.cancelLogin()
                                  CharacterList.show()
                                end })

  -- save last used character
  g_settings.set('last-used-character', charInfo.characterName)
  g_settings.set('last-used-world', charInfo.worldName)
end

local function updateWait(timeStart, timeEnd)
  if waitingWindow then
    local time = g_clock.seconds()
    if time <= timeEnd then
      local percent = ((time - timeStart) / (timeEnd - timeStart)) * 100
      local timeStr = string.format("%.0f", timeEnd - time)

      local progressBar = waitingWindow:getChildById('progressBar')
      progressBar:setPercent(percent)

      local label = waitingWindow:getChildById('timeLabel')
      label:setText(tr('Trying to reconnect in %s seconds.', timeStr))

      updateWaitEvent = scheduleEvent(function() updateWait(timeStart, timeEnd) end, 1000 * progressBar:getPercentPixels() / 100 * (timeEnd - timeStart))
      return true
    end
  end

  if updateWaitEvent then
    updateWaitEvent:cancel()
    updateWaitEvent = nil
  end
end

local function resendWait()
  if waitingWindow then
    waitingWindow:destroy()
    waitingWindow = nil

    if updateWaitEvent then
      updateWaitEvent:cancel()
      updateWaitEvent = nil
    end

    if charactersWindow then
      local selected = characterList:getFocusedChild()
      if selected then
        local charInfo = { worldHost = selected.worldHost,
                           worldPort = 7201,
                           worldName = selected.worldName,
                           characterName = selected.characterName }
        tryLogin(charInfo)
      end
    end
  end
end

local function onLoginWait(message, time)
  CharacterList.destroyLoadBox()

  waitingWindow = g_ui.displayUI('waitinglist')

  local label = waitingWindow:getChildById('infoLabel')
  label:setText(message)

  updateWaitEvent = scheduleEvent(function() updateWait(g_clock.seconds(), g_clock.seconds() + time) end, 0)
  resendWaitEvent = scheduleEvent(resendWait, time * 1000)
end

function onGameLoginError(message)
  CharacterList.destroyLoadBox()
  errorBox = displayErrorBox(tr("Login Error"), message)
  errorBox.onOk = function()
    errorBox = nil
    CharacterList.showAgain()
  end
  scheduleAutoReconnect()
end

function onGameLoginToken(unknown)
  CharacterList.destroyLoadBox()
  -- TODO: make it possible to enter a new token here / prompt token
  errorBox = displayErrorBox(tr("Two-Factor Authentification"), 'A new authentification token is required.\nPlease login again.')
  errorBox.onOk = function()
    errorBox = nil
    EnterGame.show()
  end
end

function onGameConnectionError(message, code)
  CharacterList.destroyLoadBox()
  if (not g_game.isOnline() or code ~= 2) and not errorBox then -- code 2 is normal disconnect, end of file
    local text = translateNetworkError(code, g_game.getProtocolGame() and g_game.getProtocolGame():isConnecting(), message)
    errorBox = displayErrorBox(tr("Connection Error"), text)
    errorBox.onOk = function()
      errorBox = nil
      CharacterList.showAgain()
    end
  end
  scheduleAutoReconnect()
end

function onGameUpdateNeeded(signature)
  CharacterList.destroyLoadBox()
  errorBox = displayErrorBox(tr("Update needed"), tr('Enter with your account again to update your client.'))
  errorBox.onOk = function()
    errorBox = nil
    CharacterList.showAgain()
  end 
end

function onGameEnd()
  scheduleAutoReconnect()
  CharacterList.showAgain()
end

function onLogout()
  lastLogout = g_clock.millis()
end

function scheduleAutoReconnect()
  if lastLogout + 2000 > g_clock.millis() then
    return
  end
  if autoReconnectEvent then
    removeEvent(autoReconnectEvent)   
  end
  autoReconnectEvent = scheduleEvent(executeAutoReconnect, 2500)
end

function executeAutoReconnect() 
  if not autoReconnectButton or not autoReconnectButton:isOn() or g_game.isOnline() then
    return
  end
  if errorBox then
    errorBox:destroy()
    errorBox = nil
  end
  CharacterList.doLogin()
end

-- public functions
function CharacterList.init()
  if USE_NEW_ENERGAME then return end
  connect(g_game, { onLoginError = onGameLoginError })
  connect(g_game, { onLoginToken = onGameLoginToken })
  connect(g_game, { onUpdateNeeded = onGameUpdateNeeded })
  connect(g_game, { onConnectionError = onGameConnectionError })
  connect(g_game, { onGameStart = CharacterList.destroyLoadBox })
  connect(g_game, { onLoginWait = onLoginWait })
  connect(g_game, { onGameEnd = onGameEnd })
  connect(g_game, { onLogout = onLogout })

  if G.characters then
    CharacterList.create(G.characters, G.characterAccount)
  end
end

function CharacterList.terminate()
 if USE_NEW_ENERGAME then return end
  disconnect(g_game, { onLoginError = onGameLoginError })
  disconnect(g_game, { onLoginToken = onGameLoginToken })
  disconnect(g_game, { onUpdateNeeded = onGameUpdateNeeded })
  disconnect(g_game, { onConnectionError = onGameConnectionError })
  disconnect(g_game, { onGameStart = CharacterList.destroyLoadBox })
  disconnect(g_game, { onLoginWait = onLoginWait })
  disconnect(g_game, { onGameEnd = onGameEnd })
  disconnect(g_game, { onLogout = onLogout })

  if charactersWindow then
    characterList = nil
    charactersWindow:destroy()
    charactersWindow = nil
  end

  if loadBox then
    g_game.cancelLogin()
    loadBox:destroy()
    loadBox = nil
  end

  if waitingWindow then
    waitingWindow:destroy()
    waitingWindow = nil
  end

  if updateWaitEvent then
    removeEvent(updateWaitEvent)
    updateWaitEvent = nil
  end

  if resendWaitEvent then
    removeEvent(resendWaitEvent)
    resendWaitEvent = nil
  end

  if loginEvent then
    removeEvent(loginEvent)
    loginEvent = nil
  end

  CharacterList = nil
end

function CharacterList.create(characters, account, otui)
  if not otui then otui = 'characterlist' end
  if charactersWindow then
    charactersWindow:destroy()
  end

  charactersWindow = g_ui.displayUI(otui)
  characterList = charactersWindow:getChildById('characters')
  autoReconnectButton = charactersWindow:getChildById('autoReconnect')

  -- characters
  G.characters = characters
  G.characterAccount = account

  characterList:destroyChildren()
  local accountStatusLabel = charactersWindow:getChildById('accountStatusLabel')
  local focusLabel
  for i,characterInfo in ipairs(characters) do
    local widget = g_ui.createWidget('CharacterWidget', characterList)
    for key,value in pairs(characterInfo) do
      local subWidget = widget:getChildById(key)
      if subWidget then
        if key == 'outfit' then -- it's an exception
          subWidget:setOutfit(value)
        else
          local text = value
          if subWidget.baseText and subWidget.baseTranslate then
            text = tr(subWidget.baseText, text)
          elseif subWidget.baseText then
            text = string.format(subWidget.baseText, text)
          end
          subWidget:setText(text)
        end
      end
    end

    -- these are used by login
    widget.characterName = characterInfo.name
    widget.worldName = characterInfo.worldName
    widget.worldHost = characterInfo.worldIp
    widget.worldPort = 7201

    connect(widget, { onDoubleClick = function () CharacterList.doLogin() return true end } )

    if i == 1 or (g_settings.get('last-used-character') == widget.characterName and g_settings.get('last-used-world') == widget.worldName) then
      focusLabel = widget
    end
  end

  if focusLabel then
    characterList:focusChild(focusLabel, KeyboardFocusReason)
    addEvent(function() characterList:ensureChildVisible(focusLabel) end)
  end
 
  characterList.onChildFocusChange = function()
    removeEvent(autoReconnectEvent)
    autoReconnectEvent = nil
  end

  -- account
  local status = ''
  if account.status == AccountStatus.Frozen then
    status = tr(' (Frozen)')
  elseif account.status == AccountStatus.Suspended then
    status = tr(' (Suspended)')
  end

  if account.subStatus == SubscriptionStatus.Free and account.premDays < 1 then
    accountStatusLabel:setText(('%s%s'):format(tr('Free Account'), status))
  else
    if account.premDays == 0 or account.premDays == 65535 then
      accountStatusLabel:setText(('%s%s'):format(tr('Gratis Premium Account'), status))
    else
      accountStatusLabel:setText(('%s%s'):format(tr('Premium Account (%s) days left', account.premDays), status))
    end
  end

  if account.premDays > 0 and account.premDays <= 7 then
    accountStatusLabel:setOn(true)
  else
    accountStatusLabel:setOn(false)
  end
 
  autoReconnectButton.onClick = function(widget)
    local autoReconnect = not g_settings.getBoolean('autoReconnect', true)
    autoReconnectButton:setOn(autoReconnect)
    g_settings.set('autoReconnect', autoReconnect)
  end
end

function CharacterList.destroy()
  CharacterList.hide(true)

  if charactersWindow then
    characterList = nil
    charactersWindow:destroy()
    charactersWindow = nil
  end
end

function CharacterList.show()
  if loadBox or errorBox or not charactersWindow then return end
  charactersWindow:show()
  charactersWindow:raise()
  charactersWindow:focus()
 
  local autoReconnect = g_settings.getBoolean('autoReconnect', true)
  autoReconnectButton:setOn(autoReconnect)
end

function CharacterList.hide(showLogin)
  removeEvent(autoReconnectEvent)
  autoReconnectEvent = nil

  showLogin = showLogin or false
  charactersWindow:hide()

  if showLogin and EnterGame and not g_game.isOnline() then
    EnterGame.show()
  end
end

function CharacterList.showAgain()
  if characterList and characterList:hasChildren() then
    CharacterList.show()
  end
end

function CharacterList.isVisible()
  if charactersWindow and charactersWindow:isVisible() then
    return true
  end
  return false
end

function CharacterList.doLogin()
  removeEvent(autoReconnectEvent)
  autoReconnectEvent = nil

  local selected = characterList:getFocusedChild()
  if selected then
    local charInfo = { worldHost = selected.worldHost,
                       worldPort = 7201,
                       worldName = selected.worldName,
                       characterName = selected.characterName }
    charactersWindow:hide()
    if loginEvent then
      removeEvent(loginEvent)
      loginEvent = nil
    end
    tryLogin(charInfo)
  else
    displayErrorBox(tr('Error'), tr('You must select a character to login!'))
  end
end

function CharacterList.destroyLoadBox()
  if loadBox then
    loadBox:destroy()
    loadBox = nil
  end
end

function CharacterList.cancelWait()
  if waitingWindow then
    waitingWindow:destroy()
    waitingWindow = nil
  end

  if updateWaitEvent then
    removeEvent(updateWaitEvent)
    updateWaitEvent = nil
  end

  if resendWaitEvent then
    removeEvent(resendWaitEvent)
    resendWaitEvent = nil
  end

  CharacterList.destroyLoadBox()
  CharacterList.showAgain()
end
 
@El Bringy

My gameProtocolPort is 7172
I have added to init.lua
LUA:
PROXY_IPS = {
  "2.2.2.2"
}

for _, proxyIp in pairs(PROXY_IPS) do
  g_proxy.addProxy(proxyIp, 7101, 0)
end

then copied your characterlist.lua, (changed game port to mine 7172). Still I can't log into the game

client logs:
Code:
Connecting to: 2.2.2.2:7101
Login to 127.0.0.1:7172
Login to 127.0.0.1:7172

alpha proxy logs:

Code:
[Session 3114471636] start, port: 7172
[Session 3114471636] addProxy
[Session 3114471636] onProxyPacket, id: 1 (1) last: 0 (1) size: 135
[Session 3114471636] connected to remote server
[Session 3114471636] Buffer dump (first 32 bytes): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[Session 3114471636] onHeader error: End of file
[Session 3114471636] terminate
[Proxy 7172] sendSessionEnd: 3114471636
[Proxy 7172] sendSessionEnd: 3114471636
[Proxy 7172] creating new session: 4292661240
[Session 4292661240] start, port: 7172
[Session 4292661240] addProxy
[Session 4292661240] connected to remote server
[Session 4292661240] Buffer dump (first 32 bytes): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[Session 4292661240] onHeader error: End of file
[Session 4292661240] terminate
[Proxy 7172] sendSessionEnd: 4292661240
[Proxy 7172] sendSessionEnd: 4292661240
[Proxy 7172] sendSessionEnd: 4292661240
[Proxy 7172] creating new session: 1567670144
[Session 1567670144] start, port: 7172
[Session 1567670144] addProxy
[Session 1567670144] connected to remote server
[Session 1567670144] onProxyPacket, id: 1 (1) last: 0 (1) size: 135
[Session 1567670144] Buffer dump (first 32 bytes): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[Session 1567670144] onHeader error: End of file
[Session 1567670144] terminate
[Proxy 7172] sendSessionEnd: 1567670144
[Proxy 7172] sendSessionEnd: 1567670144
[Proxy 7172] creating new session: 3321348644
[Session 3321348644] start, port: 7172
[Session 3321348644] addProxy
[Session 3321348644] onProxyPacket, id: 1 (1) last: 0 (1) size: 135
[Session 3321348644] connected to remote server
[Session 3321348644] Buffer dump (first 32 bytes): 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 48 f0 d5 5c fe 7f 00 00 00 00 00 00 00 00 00 00
[Session 3321348644] onHeader error: End of file
[Session 3321348644] terminate
[Proxy 7172] sendSessionEnd: 3321348644
[Proxy 7172] sendSessionEnd: 3321348644
 
Last edited:
actually i changed that port even in the print so you must be loading from appdata
Login to 127.0.0.1:7172<br>

g_logger.info("Login to " .. charInfo.worldHost .. ": 7201")<br>

so there is no way you are still connecting to 7171 the logger message is changed.

goto %APPDATA%/OTClientv8/
delete otclientv8 folder
 
@El Bringy
I tried now port 7201

Should I use the game port from config.lua of TFS, or a port redirected from the HAProxy reverse proxy config on the VPS where TFS is running?

Now im using this port from haproxy config.

There is a bit diffrent error in alpha proxy, but still i cannot log in to the game:
  • m_ip ip is not mine
  • onHeader error is now "Connection reset by peer"


LUA:
[Server] new connection
[Proxy 0] onHeader, connection not from HAProxy
[Proxy 0] terminate connection from m_ip = 1.0.0.127, m_proxy_ip = 1.0.0.127
[Proxy 0] Proxy::~Proxy(): m_ip = 1.0.0.127, m_proxy_ip = 1.0.0.127
[Session 1476944692] Buffer dump (first 32 bytes): 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 48 f0 d5 5c fe 7f 00 00 00 00 00 00 00 00 00 00
[Session 1476944692] onHeader error: Connection reset by peer
[Session 1476944692] terminate
[Proxy 7201] sendSessionEnd: 1476944692
[Proxy 7201] sendSessionEnd: 1476944692
[Proxy 7201] sendSessionEnd: 1476944692
[Proxy 7201] creating new session: 2266310292
[Session 2266310292] start, port: 7201
[Session 2266310292] addProxy
[Session 2266310292] connected to remote server
[Server] new connection
[Proxy 0] onHeader, connection not from HAProxy
[Proxy 0] terminate connection from m_ip = 1.0.0.127, m_proxy_ip = 1.0.0.127
[Session 2266310292] Buffer dump (first 32 bytes): 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 48 f0 d5 5c fe 7f 00 00 00 00 00 00 00 00 00 00
[Session 2266310292] onHeader error: Connection reset by peer
[Session 2266310292] terminate
[Proxy 7201] sendSessionEnd: 2266310292
[Proxy 0] Proxy::~Proxy(): m_ip = 1.0.0.127, m_proxy_ip = 1.0.0.127
[Proxy 7201] sendSessionEnd: 2266310292
[Proxy 7201] sendSessionEnd: 2266310292

client logs:

Code:
Connecting to: 2.2.2.2:7101
Login to 127.0.0.1:7201
Login to 127.0.0.1:7201
Login to 127.0.0.1:7201
 
It's hard to review all configuration and all possible network/software problems on forum. There are too many things that can go wrong.
Add me on Discord: gesior.pl
I will try to help you with config and then we will post on forum what was wrong and how we fixed it.
Post automatically merged:

There was only 1 thing wrong. Code to read IP of proxy user was added in wrong place. It must be before checking, if packet is too long. Proxy packet size (read from first 2 bytes of packet) is always too big and it blocks rest of code.

I could not connect with clean OTCv8 client, because key.pem was replaced with custom RSA key, but IDK if it was related to OTAmator problems. He is offline now, so I can't confirm, if he changed RSA key in his version of client.

Commit that fixed problem with connection:
1746782091047.webp
 
Last edited:
Solution
Back
Top