Skip to content

Commit 9e2df4e

Browse files
authored
[GEN][ZH] Implement Network Lobby support for multi instance clients (#906)
1 parent 01e364b commit 9e2df4e

File tree

10 files changed

+150
-96
lines changed

10 files changed

+150
-96
lines changed

Generals/Code/GameEngine/Include/GameNetwork/IPEnumeration.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ class IPEnumeration
7373
AsciiString getMachineName( void ); ///< Return the Network Neighborhood machine name
7474

7575
protected:
76+
void addNewIP( UnsignedByte a, UnsignedByte b, UnsignedByte c, UnsignedByte d );
7677

7778
EnumeratedIP *m_IPlist;
7879
Bool m_isWinsockInitialized;

Generals/Code/GameEngine/Include/GameNetwork/networkutil.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "GameNetwork/NetworkDefs.h"
3131
#include "GameNetwork/NetworkInterface.h"
3232

33+
UnsignedInt AssembleIp(UnsignedByte a, UnsignedByte b, UnsignedByte c, UnsignedByte d);
3334
UnsignedInt ResolveIP(AsciiString host);
3435
UnsignedShort GenerateNextCommandID();
3536
Bool DoesCommandRequireACommandID(NetCommandType type);
@@ -47,4 +48,12 @@ void dumpBufferToLog(const void *vBuf, Int len, const char *fname, Int line);
4748
#define LOGBUFFER(buf, len) {}
4849
#endif // DEBUG_LOGGING
4950

51+
inline UnsignedInt AssembleIp(UnsignedByte a, UnsignedByte b, UnsignedByte c, UnsignedByte d)
52+
{
53+
return ((UnsignedInt)(a) << 24) |
54+
((UnsignedInt)(b) << 16) |
55+
((UnsignedInt)(c) << 8) |
56+
((UnsignedInt)(d));
57+
}
58+
5059
#endif

Generals/Code/GameEngine/Source/GameClient/ClientInstance.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ bool ClientInstance::initialize()
3636
// WARNING: DO NOT use this number for any other application except Generals.
3737
while (true)
3838
{
39-
#ifdef RTS_MULTI_INSTANCE
39+
#if defined(RTS_MULTI_INSTANCE)
4040
std::string guidStr = getFirstInstanceName();
4141
if (s_instanceIndex > 0u)
4242
{

Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/LanLobbyMenu.cpp

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -96,23 +96,30 @@ Bool LANPreferences::loadFromIniFile()
9696
UnicodeString LANPreferences::getUserName(void)
9797
{
9898
UnicodeString ret;
99+
99100
LANPreferences::const_iterator it = find("UserName");
100-
if (it == end())
101+
if (it != end())
101102
{
102-
IPEnumeration IPs;
103-
ret.translate(IPs.getMachineName());
104-
return ret;
103+
// Found an user name. Use it if valid.
104+
ret = QuotedPrintableToUnicodeString(it->second);
105+
ret.trim();
106+
if (!ret.isEmpty())
107+
{
108+
return ret;
109+
}
105110
}
106111

107-
ret = QuotedPrintableToUnicodeString(it->second);
108-
ret.trim();
109-
if (ret.isEmpty())
112+
if (rts::ClientInstance::getInstanceId() > 1u)
110113
{
111-
IPEnumeration IPs;
112-
ret.translate(IPs.getMachineName());
114+
// TheSuperHackers @feature Use the instance id as default user name
115+
// to avoid duplicate names for multiple client instances.
116+
ret.format(L"Instance%.2d", rts::ClientInstance::getInstanceId());
113117
return ret;
114118
}
115-
119+
120+
// Use machine name as default user name.
121+
IPEnumeration IPs;
122+
ret.translate(IPs.getMachineName());
116123
return ret;
117124
}
118125

Generals/Code/GameEngine/Source/GameNetwork/IPEnumeration.cpp

Lines changed: 47 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
2626

2727
#include "GameNetwork/IPEnumeration.h"
28+
#include "GameNetwork/networkutil.h"
29+
#include "GameClient/ClientInstance.h"
2830

2931
IPEnumeration::IPEnumeration( void )
3032
{
@@ -84,7 +86,7 @@ EnumeratedIP * IPEnumeration::getAddresses( void )
8486
HOSTENT* hostEnt = gethostbyname(hostname);
8587
if (hostEnt == NULL)
8688
{
87-
DEBUG_LOG(("Failed call to gethostnyname; WSAGetLastError returned %d\n", WSAGetLastError()));
89+
DEBUG_LOG(("Failed call to gethostbyname; WSAGetLastError returned %d\n", WSAGetLastError()));
8890
return NULL;
8991
}
9092

@@ -94,62 +96,70 @@ EnumeratedIP * IPEnumeration::getAddresses( void )
9496
DEBUG_LOG(("gethostbyname returns oddly-sized IP addresses!\n"));
9597
return NULL;
9698
}
97-
99+
100+
#if defined(RTS_MULTI_INSTANCE)
101+
// TheSuperHackers @feature Add one unique local host IP address for each multi client instance.
102+
const UnsignedInt id = rts::ClientInstance::getInstanceId();
103+
addNewIP(
104+
127,
105+
(UnsignedByte)(id >> 16),
106+
(UnsignedByte)(id >> 8),
107+
(UnsignedByte)(id));
108+
#endif
109+
98110
// construct a list of addresses
99111
int numAddresses = 0;
100112
char *entry;
101113
while ( (entry = hostEnt->h_addr_list[numAddresses++]) != 0 )
102114
{
103-
EnumeratedIP *newIP = newInstance(EnumeratedIP);
115+
addNewIP(
116+
(UnsignedByte)entry[0],
117+
(UnsignedByte)entry[1],
118+
(UnsignedByte)entry[2],
119+
(UnsignedByte)entry[3]);
120+
}
104121

105-
AsciiString str;
106-
str.format("%d.%d.%d.%d", (unsigned char)entry[0], (unsigned char)entry[1], (unsigned char)entry[2], (unsigned char)entry[3]);
122+
return m_IPlist;
123+
}
124+
125+
void IPEnumeration::addNewIP( UnsignedByte a, UnsignedByte b, UnsignedByte c, UnsignedByte d )
126+
{
127+
EnumeratedIP *newIP = newInstance(EnumeratedIP);
107128

108-
UnsignedInt testIP = *((UnsignedInt *)entry);
109-
UnsignedInt ip = ntohl(testIP);
129+
AsciiString str;
130+
str.format("%d.%d.%d.%d", (int)a, (int)b, (int)c, (int)d);
110131

111-
/*
112-
ip = *entry++;
113-
ip <<= 8;
114-
ip += *entry++;
115-
ip <<= 8;
116-
ip += *entry++;
117-
ip <<= 8;
118-
ip += *entry++;
119-
*/
132+
UnsignedInt ip = AssembleIp(a, b, c, d);
120133

121-
newIP->setIPstring(str);
122-
newIP->setIP(ip);
134+
newIP->setIPstring(str);
135+
newIP->setIP(ip);
123136

124-
DEBUG_LOG(("IP: 0x%8.8X / 0x%8.8X (%s)\n", testIP, ip, str.str()));
137+
DEBUG_LOG(("IP: 0x%8.8X (%s)\n", ip, str.str()));
125138

126-
// Add the IP to the list in ascending order
127-
if (!m_IPlist)
139+
// Add the IP to the list in ascending order
140+
if (!m_IPlist)
141+
{
142+
m_IPlist = newIP;
143+
newIP->setNext(NULL);
144+
}
145+
else
146+
{
147+
if (newIP->getIP() < m_IPlist->getIP())
128148
{
149+
newIP->setNext(m_IPlist);
129150
m_IPlist = newIP;
130-
newIP->setNext(NULL);
131151
}
132152
else
133153
{
134-
if (newIP->getIP() < m_IPlist->getIP())
154+
EnumeratedIP *p = m_IPlist;
155+
while (p->getNext() && p->getNext()->getIP() < newIP->getIP())
135156
{
136-
newIP->setNext(m_IPlist);
137-
m_IPlist = newIP;
138-
}
139-
else
140-
{
141-
EnumeratedIP *p = m_IPlist;
142-
while (p->getNext() && p->getNext()->getIP() < newIP->getIP())
143-
{
144-
p = p->getNext();
145-
}
146-
newIP->setNext(p->getNext());
147-
p->setNext(newIP);
157+
p = p->getNext();
148158
}
159+
newIP->setNext(p->getNext());
160+
p->setNext(newIP);
149161
}
150162
}
151-
152-
return m_IPlist;
153163
}
154164

155165
AsciiString IPEnumeration::getMachineName( void )

GeneralsMD/Code/GameEngine/Include/GameNetwork/IPEnumeration.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ class IPEnumeration
7373
AsciiString getMachineName( void ); ///< Return the Network Neighborhood machine name
7474

7575
protected:
76+
void addNewIP( UnsignedByte a, UnsignedByte b, UnsignedByte c, UnsignedByte d );
7677

7778
EnumeratedIP *m_IPlist;
7879
Bool m_isWinsockInitialized;

GeneralsMD/Code/GameEngine/Include/GameNetwork/networkutil.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "GameNetwork/NetworkDefs.h"
3131
#include "GameNetwork/NetworkInterface.h"
3232

33+
UnsignedInt AssembleIp(UnsignedByte a, UnsignedByte b, UnsignedByte c, UnsignedByte d);
3334
UnsignedInt ResolveIP(AsciiString host);
3435
UnsignedShort GenerateNextCommandID();
3536
Bool DoesCommandRequireACommandID(NetCommandType type);
@@ -47,4 +48,12 @@ void dumpBufferToLog(const void *vBuf, Int len, const char *fname, Int line);
4748
#define LOGBUFFER(buf, len) {}
4849
#endif // DEBUG_LOGGING
4950

51+
inline UnsignedInt AssembleIp(UnsignedByte a, UnsignedByte b, UnsignedByte c, UnsignedByte d)
52+
{
53+
return ((UnsignedInt)(a) << 24) |
54+
((UnsignedInt)(b) << 16) |
55+
((UnsignedInt)(c) << 8) |
56+
((UnsignedInt)(d));
57+
}
58+
5059
#endif

GeneralsMD/Code/GameEngine/Source/GameClient/ClientInstance.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ bool ClientInstance::initialize()
3636
// WARNING: DO NOT use this number for any other application except Generals.
3737
while (true)
3838
{
39-
#ifdef RTS_MULTI_INSTANCE
39+
#if defined(RTS_MULTI_INSTANCE)
4040
std::string guidStr = getFirstInstanceName();
4141
if (s_instanceIndex > 0u)
4242
{

GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/LanLobbyMenu.cpp

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -96,23 +96,30 @@ Bool LANPreferences::loadFromIniFile()
9696
UnicodeString LANPreferences::getUserName(void)
9797
{
9898
UnicodeString ret;
99+
99100
LANPreferences::const_iterator it = find("UserName");
100-
if (it == end())
101+
if (it != end())
101102
{
102-
IPEnumeration IPs;
103-
ret.translate(IPs.getMachineName());
104-
return ret;
103+
// Found an user name. Use it if valid.
104+
ret = QuotedPrintableToUnicodeString(it->second);
105+
ret.trim();
106+
if (!ret.isEmpty())
107+
{
108+
return ret;
109+
}
105110
}
106111

107-
ret = QuotedPrintableToUnicodeString(it->second);
108-
ret.trim();
109-
if (ret.isEmpty())
112+
if (rts::ClientInstance::getInstanceId() > 1u)
110113
{
111-
IPEnumeration IPs;
112-
ret.translate(IPs.getMachineName());
114+
// TheSuperHackers @feature Use the instance id as default user name
115+
// to avoid duplicate names for multiple client instances.
116+
ret.format(L"Instance%.2d", rts::ClientInstance::getInstanceId());
113117
return ret;
114118
}
115-
119+
120+
// Use machine name as default user name.
121+
IPEnumeration IPs;
122+
ret.translate(IPs.getMachineName());
116123
return ret;
117124
}
118125

0 commit comments

Comments
 (0)