Welcome!

Join our community of MMO enthusiasts and game developers! By registering, you'll gain access to discussions on the latest developments in MMO server files and collaborate with like-minded individuals. Join us today and unlock the potential of MMO server development!

Join Today!

[Share] Source Code implementation of IP interceptor

Initiate Mage
Joined
Dec 26, 2020
Messages
10
Reaction score
6
If you want to host a Ran server behind a router or VPN and don't want to use an IP interceptor, here's what you need to edit in the source. This feature works best for VPN services with Port Forwarding features.


Requirements:
- Knowledge with C++
- knowledge on Port Forwarding

Files that need to be edited:

s_CCfg.h
Find the line:
Code:
TCHAR*                   GetSessionServerIP(void);
int                      GetSessionServerPort(void);

Replace with:

Code:
TCHAR*                                                GetSessionServerIP(void);
int                                                   GetSessionServerPort(void);
               
const TCHAR*                    GetProxyIp(const TCHAR* szDefaultVal);

Add this:
Code:
private:
bool m_bUseProxyIp;
TCHAR m_szProxyIp[MAX_IP_LENGTH+1];

s_CCfg.cpp
add on method SetDefault(void)
Code:
m_bUseProxyIp = false;

Add this on Process(TCHAR * szLine)
Code:
else if (_tcscmp(token, "use_ip_proxy") == 0)
                                {
                                                token = ::_tcstok(NULL, seps);
                                                if (token)
                                                {
                                                                if (::_tstoi(token))                            m_bUseProxyIp = true;
                                                                else                                                                        m_bUseProxyIp = false;
                                                }
                                                else
                                                                return 0;
                                }
 
                                else if (_tcscmp(token, "ip_proxy") == 0)
                                {
                                                // ip_proxy [ip here]
                                                token = ::_tcstok(NULL, seps);
                                                if (token)
                                                                ::StringCchCopy(m_szProxyIp, MAX_IP_LENGTH + 1, token);
                                                else
                                                                return 0;
                                }

Add at the end of s_CCfg.cpp:
Code:
const TCHAR* CCfg::GetProxyIp(const TCHAR* szDefaultValue)
    {
        if (m_bUseProxyIp)
            return m_szProxyIp;
        else
            return szDefaultValue;
    }


s_CAgentServerMsg.cpp
Code:
int CAgentServer::MsgLobbyCharJoinField(MSG_LIST* pMsg)
    {
        if (pMsg == NULL) return NET_ERROR;
 
        DWORD dwClient = pMsg->dwClient - (DWORD) m_nMaxClient;
        NET_GAME_JOIN_FIELDSVR_FB* pMsgJoinFB = (NET_GAME_JOIN_FIELDSVR_FB*) pMsg->Buffer;
 
        if (pMsgJoinFB == NULL) return NET_ERROR;
 
        int nChannel = m_pClientManager->GetChannel(dwClient);
       
        F_SERVER_INFO* pField = CCfg::GetInstance()->GetFieldServer ( (int) pMsgJoinFB->dwFieldSVR, nChannel );
       
        // Check GaeaID
        if ( pMsgJoinFB->dwGaeaID != m_pClientManager->GetGaeaID(dwClient) )                  return NET_ERROR;
        m_pClientManager->SetSlotFieldAgent ( dwClient, pMsgJoinFB->dwSlotFieldAgent );
       
        NET_CONNECT_CLIENT_TO_FIELD MsgConnect;
        MsgConnect.dwGaeaID = m_pClientManager->GetGaeaID(dwClient);
        MsgConnect.dwSlotFieldAgent = m_pClientManager->GetSlotFieldAgent(dwClient);
        MsgConnect.emType = pMsgJoinFB->emType;
 
        [COLOR=#ff0000]::StringCchCopy( MsgConnect.szServerIP, MAX_IP_LENGTH+1, CCfg::GetInstance()->GetProxyIp(pField->szServerIP) );[/COLOR]
        MsgConnect.nServicePort = pField->nServicePort;
 
        // m_pClientManager->GetChaNum(dwClient);
 
        return SendClient ( dwClient, &MsgConnect );
    }


s_LoginServerSession.cpp
Code:
void CLoginServer::SessionSndSvrInfo(void)
    {
        NET_SERVER_INFO nsi;
        int nSize;
       
        nSize = sizeof(NET_SERVER_INFO);
        ::memset(&nsi, 0, nSize);
        nsi.nmg.dwSize = nSize;
        nsi.nmg.nType = NET_MSG_SND_FULL_SVR_INFO;
       
        nsi.gsi.nServerCurrentClient               = m_pClientManager->GetCurrentClientNumber();
        nsi.gsi.nServerGroup                                             = m_nServerGroup;
        nsi.gsi.nServerChannel          = m_nServerChannel;
        nsi.gsi.nServerMaxClient                     = m_pClientManager->GetMaxClient(); 
        nsi.gsi.nServicePort                                = m_nPort;
        nsi.gsi.nServerType                                                = SERVER_LOGIN;
 
        [COLOR=#ff0000]::StringCchCopy(nsi.gsi.szServerIP, MAX_IP_LENGTH+1, CCfg::GetInstance()->GetProxyIp(m_szAddress));[/COLOR]
 
        SendSession(&nsi);
    }


s_CFieldServerSession.cpp
Code:
int CFieldServer::SessionSndSvrInfo()
    {
        int nSize;
        NET_SERVER_INFO nsi;
       
        nSize = sizeof(NET_SERVER_INFO);
        ::memset(&nsi, 0, nSize);
       
        nsi.nmg.dwSize                                                                       = nSize;
        nsi.nmg.nType                                                                         = NET_MSG_SND_FULL_SVR_INFO;
        nsi.gsi.nControlPort                                               = CCfg::GetInstance()->GetControlPort();
        nsi.gsi.nServerCurrentClient               = m_pClientManager->GetCurrentClientNumber();
        nsi.gsi.nServerGroup                                             = CCfg::GetInstance()->GetServerGroup();
        nsi.gsi.nServerMaxClient                     = CCfg::GetInstance()->GetServerMaxClient();
        nsi.gsi.nServerNumber                                         = CCfg::GetInstance()->GetServerNumber();
        nsi.gsi.nServerType                                                = CCfg::GetInstance()->GetServerType();
        nsi.gsi.nServerChannel          = CCfg::GetInstance()->GetServerChannel();
        nsi.gsi.nServicePort                                = CCfg::GetInstance()->GetServicePort();              
        // ::memcpy(nsi.gsi.szServerIP, m_szAddress, MAX_IP_LENGTH);
        [COLOR=#ff0000]StringCchCopy(nsi.gsi.szServerIP, MAX_IP_LENGTH+1, CCfg::GetInstance()->GetProxyIp(m_szAddress));[/COLOR]
       
        if (SendSession(&nsi) == NET_ERROR)
        {
            CConsoleMessage::GetInstance()->Write(LOG_CONSOLE, _T("ERROR:SessionSndSvrInfo NET_ERROR"));
            return NET_ERROR;
        }
        else
        {
            CConsoleMessage::GetInstance()->Write(LOG_CONSOLE, _T("INFO:SessionSndSvrInfo %s"), m_szAddress);
            return NET_OK;
        }
    }


s_CAgentServerSession.cpp
Code:
int CAgentServer::SessionSndSvrInfo(void)
{             
                NET_SERVER_INFO nsi;
                nsi.nmg.nType                                                                  = NET_MSG_SND_FULL_SVR_INFO;
                nsi.gsi.nControlPort                                        = CCfg::GetInstance()->GetControlPort();
                nsi.gsi.nServerCurrentClient       = m_pClientManager->GetCurrentClientNumber();
                nsi.gsi.nServerGroup                                      = CCfg::GetInstance()->GetServerGroup();
                nsi.gsi.nServerMaxClient                              = CCfg::GetInstance()->GetServerMaxClient();
                nsi.gsi.nServerNumber                                  = CCfg::GetInstance()->GetServerNumber();
                nsi.gsi.nServerType                                                         = CCfg::GetInstance()->GetServerType();
                nsi.gsi.nServicePort                                        = CCfg::GetInstance()->GetServicePort();
                nsi.gsi.nServerChannel          = CCfg::GetInstance()->GetServerChannel();
                nsi.gsi.nServerChannelNumber    = CCfg::GetInstance()->GetServerChannelNumber();
                nsi.gsi.nServerChannellMaxClient= CCfg::GetInstance()->GetServerChannelMaxClient();
 
                // proxy address
                [COLOR=#ff0000]StringCchCopy( nsi.gsi.szServerIP, MAX_IP_LENGTH+1, CCfg::GetInstance()->GetProxyIp(m_szAddress) );[/COLOR]
 
                CConsoleMessage::GetInstance()->Write(
                                _T("SessionSndSvrInfo %s CH:%d"),
                                m_szAddress,
                                nsi.gsi.nServerChannelNumber );
               
                if (SendSession(&nsi) == NET_ERROR)
                {
                                return NET_ERROR;
                }
                else
                {
                                for (int i=0; i<CCfg::GetInstance()->GetServerChannelNumber(); ++i)
                                {
                                                SessionSndChannelState(i);
                                }
                                return NET_OK;
                }
}

How to implement on your server:
1. Forward all your LoginServer, FieldServer, AgentServer ports (assuming you have your session server set to localhost)

2. Set your LAN IP as your "server_ip" in the CFGs for Login, Field, and Agent (The same as what you would do if you were to use an IP interceptor).

3. Add this to your LoginServer.cfg, FieldServer.cfg, AgentServer.cfg:
Code:
use_ip_proxy      1
ip_proxy          [dynamic ip]


Disclaimer: I have only tested this in a hurry. Use at your own risk
 
Last edited:
Joined
Feb 4, 2014
Messages
962
Reaction score
36
If you want to host a Ran server behind a router or VPN and don't want to use an IP interceptor, here's what you need to edit in the source. This feature works best for VPN services with Port Forwarding features.

Question: What should be put in Field and Agent Server as IP? Local IP and 127.0.0.1 could be work?

Thanks.
 
Initiate Mage
Joined
Dec 26, 2020
Messages
10
Reaction score
6
Question: What should be put in Field and Agent Server as IP? Local IP and 127.0.0.1 could be work?

Thanks.

No you would not want to set it to localhost as winsock API will only read traffic coming from 127.0.0.1 which the packet would not come from as the router would reroute the packet to the LAN IP. Best if you use LAN IP.
 
Initiate Mage
Joined
Dec 26, 2020
Messages
10
Reaction score
6
dynamic ip is consist of many ips, should we put all the IPs there with comma? like...
No, no, your dynamic IP is what you would get if you go to whatismyip.c0m
You just need the 1 ip.. most likely just one of those IPs
 
Last edited:
Banned
Banned
Joined
Nov 6, 2020
Messages
113
Reaction score
21
Code:
private:
bool     m_bUseProxyIp;

should be corrected to

Code:
protected:
bool m_bUseProxyIp;
TCHAR m_szProxyIp[MAX_IP_LENGTH+1];
?
 
Joined
Feb 4, 2014
Messages
962
Reaction score
36
Base on my test:

Agent Server Detect LocalIP
Field Server Detect ProxyIP

Result: Cant enter the game after click the character

Note: If you disable Proxy in AgentServer you can enter the game.
 
Last edited:
Banned
Banned
Joined
Nov 6, 2020
Messages
113
Reaction score
21
I stuck up in the Server Selection screen...
Here is the screenshot of the session server. (using lan ip for it)
ran - [Share] Source Code implementation of IP interceptor - RaGEZONE Forums

I have set all the port forwarding and turned on the ip proxy in the agent,
however, the agent server ip is still the lan ip.
 

Attachments

You must be registered for see attachments list
Last edited:
Initiate Mage
Joined
Dec 26, 2020
Messages
10
Reaction score
6
Code:
private:
bool     m_bUseProxyIp;

should be corrected to

Code:
protected:
bool m_bUseProxyIp;
TCHAR m_szProxyIp[MAX_IP_LENGTH+1];
?

thanks, I totally missed that one..


Base on my test:

Agent Server Detect LocalIP
Field Server Detect ProxyIP

Result: Cant enter the game after click the character

Note: If you disable Proxy in AgentServer you can enter the game.

I stuck up in the Server Selection screen...
Here is the screenshot of the session server. (using lan ip for it)
View attachment 169102

I have set all the port forwarding and turned on the ip proxy in the agent,
however, the agent server ip is still the lan ip.

That's quite weird, usually the agent server is the one to send the Field IP and Port to the players/clients.. can you send me your CFGs?
 
Banned
Banned
Joined
Nov 6, 2020
Messages
113
Reaction score
21
Well, when I edited s_CAgentServerSession.cpp, it works.
Code:
int CFieldServer::SessionSndSvrInfo()
{
    int nSize;
    NET_SERVER_INFO nsi;

    nSize = sizeof(NET_SERVER_INFO);
    ::memset(&nsi, 0, nSize);

    nsi.nmg.dwSize = nSize;
    nsi.nmg.nType = NET_MSG_SND_FULL_SVR_INFO;
    nsi.gsi.nControlPort = CCfg::GetInstance()->GetControlPort();
    nsi.gsi.nServerCurrentClient = m_pClientManager->GetCurrentClientNumber();
    nsi.gsi.nServerGroup = CCfg::GetInstance()->GetServerGroup();
    nsi.gsi.nServerMaxClient = CCfg::GetInstance()->GetServerMaxClient();
    nsi.gsi.nServerNumber = CCfg::GetInstance()->GetServerNumber();
    nsi.gsi.nServerType = CCfg::GetInstance()->GetServerType();
    nsi.gsi.nServerChannel = CCfg::GetInstance()->GetServerChannel();
    nsi.gsi.nServicePort = CCfg::GetInstance()->GetServicePort();
    // ::memcpy(nsi.gsi.szServerIP, m_szAddress, MAX_IP_LENGTH);

[COLOR=#FF0000]    StringCchCopy(nsi.gsi.szServerIP, MAX_IP_LENGTH + 1, CCfg::GetInstance()->GetProxyIp(m_szAddress));
[/COLOR]
    if (SendSession(&nsi) == NET_ERROR)
    {
        CConsoleMessage::GetInstance()->Write(LOG_CONSOLE, _T("ERROR:SessionSndSvrInfo NET_ERROR"));
        return NET_ERROR;
    }
    else
    {
        CConsoleMessage::GetInstance()->Write(LOG_CONSOLE, _T("INFO:SessionSndSvrInfo %s"), m_szAddress);
        return NET_OK;
    }
}
 
Last edited:
Initiate Mage
Joined
Dec 26, 2020
Messages
10
Reaction score
6
Well, when I edited s_CFieldServerSession.cpp, it works.
Code:
int CFieldServer::SessionSndSvrInfo()
{
    int nSize;
    NET_SERVER_INFO nsi;

    nSize = sizeof(NET_SERVER_INFO);
    ::memset(&nsi, 0, nSize);

    nsi.nmg.dwSize = nSize;
    nsi.nmg.nType = NET_MSG_SND_FULL_SVR_INFO;
    nsi.gsi.nControlPort = CCfg::GetInstance()->GetControlPort();
    nsi.gsi.nServerCurrentClient = m_pClientManager->GetCurrentClientNumber();
    nsi.gsi.nServerGroup = CCfg::GetInstance()->GetServerGroup();
    nsi.gsi.nServerMaxClient = CCfg::GetInstance()->GetServerMaxClient();
    nsi.gsi.nServerNumber = CCfg::GetInstance()->GetServerNumber();
    nsi.gsi.nServerType = CCfg::GetInstance()->GetServerType();
    nsi.gsi.nServerChannel = CCfg::GetInstance()->GetServerChannel();
    nsi.gsi.nServicePort = CCfg::GetInstance()->GetServicePort();
    // ::memcpy(nsi.gsi.szServerIP, m_szAddress, MAX_IP_LENGTH);

[COLOR=#FF0000]    StringCchCopy(nsi.gsi.szServerIP, MAX_IP_LENGTH + 1, CCfg::GetInstance()->GetProxyIp(m_szAddress));
[/COLOR]
    if (SendSession(&nsi) == NET_ERROR)
    {
        CConsoleMessage::GetInstance()->Write(LOG_CONSOLE, _T("ERROR:SessionSndSvrInfo NET_ERROR"));
        return NET_ERROR;
    }
    else
    {
        CConsoleMessage::GetInstance()->Write(LOG_CONSOLE, _T("INFO:SessionSndSvrInfo %s"), m_szAddress);
        return NET_OK;
    }
}
So you just missed a step??
 
Banned
Banned
Joined
Nov 6, 2020
Messages
113
Reaction score
21
So you just missed a step??
OHH... I copy the wrong file...
I mean s_CAgentServerSession.cpp which not be mentioned.
not s_CFieldServerSession.cpp

Tested in the Google VPC,
Work well, nice!
Thank you for sharing it.
ran2 - [Share] Source Code implementation of IP interceptor - RaGEZONE Forums


 

Attachments

You must be registered for see attachments list
Initiate Mage
Joined
Dec 26, 2020
Messages
10
Reaction score
6
OHH... I copy the wrong file...
I mean s_CAgentServerSession.cpp which not be mentioned.
not s_CFieldServerSession.cpp

Tested in the Google VPC,
Work well, nice!
Thank you for sharing it.
View attachment 169105



That's Exactly the purpose of it!! You're welcome! I'm still trying to make sure it works 100%

edit:
I updated the post you are supposed to changed s_CAgentServerSession.cpp too I forgot to add it.
 
Last edited:
Initiate Mage
Joined
Aug 18, 2020
Messages
4
Reaction score
0
Anyone can help? I follow the process and I was able to compile it without error but still when I click the server name it says server connection failed. All ports are open btw I am using a Azure VM.
 
Last edited:
Back
Top