Skip to content

Commit 5be46cf

Browse files
committed
Allow binding to specific IP address
closes #264 Add server bind address field to network options
1 parent 09948d0 commit 5be46cf

File tree

7 files changed

+119
-44
lines changed

7 files changed

+119
-44
lines changed

source/glest_game/main/main.cpp

+24
Original file line numberDiff line numberDiff line change
@@ -5499,6 +5499,30 @@ int glestMain(int argc, char **argv) {
54995499
}
55005500
}
55015501

5502+
else if (hasCommandArgument(
5503+
argc, argv, GAME_ARGS[GAME_ARG_SERVER_BIND_ADDRESS]) == true) {
5504+
int foundParamIndIndex = -1;
5505+
hasCommandArgument(
5506+
argc, argv,
5507+
string(GAME_ARGS[GAME_ARG_SERVER_BIND_ADDRESS]) + string("="),
5508+
&foundParamIndIndex);
5509+
if (foundParamIndIndex < 0) {
5510+
hasCommandArgument(argc, argv,
5511+
string(GAME_ARGS[GAME_ARG_SERVER_BIND_ADDRESS]),
5512+
&foundParamIndIndex);
5513+
}
5514+
string paramValue = argv[foundParamIndIndex];
5515+
vector<string> paramPartTokens;
5516+
Tokenize(paramValue, paramPartTokens, "=");
5517+
if (paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
5518+
string itemName = paramPartTokens[1];
5519+
5520+
Config &config = Config::getInstance();
5521+
config.setString("ServerBindAddress", itemName);
5522+
// ServerSocket::setBindAddress(itemName);
5523+
}
5524+
}
5525+
55025526
if (hasCommandArgument(argc, argv,
55035527
string(GAME_ARGS[GAME_ARG_MASTERSERVER_STATUS])) ==
55045528
true) {

source/glest_game/menu/menu_state_options_network.cpp

+59-28
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ MenuStateOptionsNetwork::MenuStateOptionsNetwork(Program *program,
5252
mainMessageBox("Options_Network", "mainMessageBox"),
5353

5454
labelExternalPort("Options_Network", "labelExternalPort"),
55+
labelServerBindIpLabel("Options_Network", "labelServerBindIpLabel"),
56+
labelServerBindIp("Options_Network", "labelServerBindIp"),
5557
labelServerPortLabel("Options_Network", "labelServerPortLabel"),
5658

5759
labelPublishServerExternalPort("Options_Network",
@@ -91,6 +93,7 @@ MenuStateOptionsNetwork::MenuStateOptionsNetwork(Program *program,
9193
Config &config = Config::getInstance();
9294
this->parentUI = parentUI;
9395
this->console.setOnlyChatMessagesInStoredLines(false);
96+
this->activeInputLabel = NULL;
9497

9598
int leftLabelStart = 100;
9699
int leftColumnStart = leftLabelStart + 300;
@@ -152,8 +155,21 @@ MenuStateOptionsNetwork::MenuStateOptionsNetwork(Program *program,
152155
extPort = "!!! " + extPort + " !!!";
153156
}
154157
labelExternalPort.setText(extPort);
158+
currentLine -= lineOffset;
155159

160+
// Server bind IP
161+
labelServerBindIpLabel.init(currentLabelStart, currentLine);
162+
labelServerBindIpLabel.setText(lang.getString("ServerBindIP"));
163+
164+
labelServerBindIp.init(currentColumnStart, currentLine);
165+
labelServerBindIp.setText(config.getString("ServerBindAddress", ""));
166+
labelServerBindIp.setFont(CoreData::getInstance().getMenuFontBig());
167+
labelServerBindIp.setFont3D(CoreData::getInstance().getMenuFontBig3D());
168+
labelServerBindIp.setEditable(true);
169+
labelServerBindIp.setMaxEditWidth(16);
170+
labelServerBindIp.setMaxEditRenderWidth(200);
156171
currentLine -= lineOffset;
172+
157173
// server port
158174
labelServerPortLabel.init(currentLabelStart, currentLine);
159175
labelServerPortLabel.setText(lang.getString("ServerPort"));
@@ -292,6 +308,7 @@ void MenuStateOptionsNetwork::reloadUI() {
292308
}
293309

294310
labelServerPortLabel.setText(lang.getString("ServerPort"));
311+
labelServerBindIpLabel.setText(lang.getString("ServerBindAddress"));
295312
labelPublishServerExternalPort.setText(
296313
lang.getString("PublishServerExternalPort"));
297314
labelEnableFTP.setText(lang.getString("EnableFTP"));
@@ -347,6 +364,9 @@ void MenuStateOptionsNetwork::mouseClick(int x, int y,
347364
}
348365
mainMenu->setState(new MenuStateRoot(program, mainMenu));
349366
return;
367+
} else if (labelServerBindIp.mouseClick(x, y) &&
368+
(activeInputLabel != &labelServerBindIp)) {
369+
this->setActiveInputLabel(&labelServerBindIp);
350370
} else if (buttonAudioSection.mouseClick(x, y)) {
351371
soundRenderer.playFx(coreData.getClickSoundA());
352372
mainMenu->setState(new MenuStateOptionsSound(
@@ -422,35 +442,29 @@ void MenuStateOptionsNetwork::mouseMove(int x, int y, const MouseState *ms) {
422442
}
423443

424444
// bool MenuStateOptionsNetwork::isInSpecialKeyCaptureEvent() {
425-
// return (activeInputLabel != NULL);
426-
// }
427-
//
428-
// void MenuStateOptionsNetwork::keyDown(SDL_KeyboardEvent key) {
429-
// if(activeInputLabel != NULL) {
430-
// keyDownEditLabel(key, &activeInputLabel);
431-
// }
432-
// }
445+
// return (activeInputLabel != NULL);
446+
//}
447+
448+
void MenuStateOptionsNetwork::keyDown(SDL_KeyboardEvent key) {
449+
if (activeInputLabel != NULL) {
450+
keyDownEditLabel(key, &activeInputLabel);
451+
}
452+
}
433453

434454
void MenuStateOptionsNetwork::keyPress(SDL_KeyboardEvent c) {
435-
// if(activeInputLabel != NULL) {
436-
// //printf("[%d]\n",c); fflush(stdout);
437-
// if( &labelPlayerName == activeInputLabel ||
438-
// &labelTransifexUser == activeInputLabel ||
439-
// &labelTransifexPwd == activeInputLabel ||
440-
// &labelTransifexI18N == activeInputLabel) {
441-
// textInputEditLabel(c, &activeInputLabel);
442-
// }
443-
// }
444-
// else {
445-
Config &configKeys = Config::getInstance(
446-
std::pair<ConfigType, ConfigType>(cfgMainKeys, cfgUserKeys));
447-
if (isKeyPressed(configKeys.getSDLKey("SaveGUILayout"), c) == true) {
448-
GraphicComponent::saveAllCustomProperties(containerName);
449-
// Lang &lang= Lang::getInstance();
450-
// console.addLine(lang.getString("GUILayoutSaved") + " [" + (saved ?
451-
// lang.getString("Yes") : lang.getString("No"))+ "]");
455+
if (activeInputLabel != NULL) {
456+
keyPressEditLabel(c, &activeInputLabel);
457+
} else {
458+
Config &configKeys = Config::getInstance(
459+
std::pair<ConfigType, ConfigType>(cfgMainKeys, cfgUserKeys));
460+
if (isKeyPressed(configKeys.getSDLKey("SaveGUILayout"), c) == true) {
461+
GraphicComponent::saveAllCustomProperties(containerName);
462+
// Lang &lang= Lang::getInstance();
463+
// console.addLine(lang.getString("GUILayoutSaved") + " [" + (saved ?
464+
// lang.getString("Yes") : lang.getString("No"))+ "]");
465+
}
466+
// }
452467
}
453-
// }
454468
}
455469

456470
void MenuStateOptionsNetwork::render() {
@@ -467,6 +481,8 @@ void MenuStateOptionsNetwork::render() {
467481
renderer.renderButton(&buttonMiscSection);
468482
renderer.renderButton(&buttonNetworkSettings);
469483
renderer.renderLabel(&labelServerPortLabel);
484+
renderer.renderLabel(&labelServerBindIpLabel);
485+
renderer.renderLabel(&labelServerBindIp);
470486
renderer.renderLabel(&labelExternalPort);
471487
renderer.renderLabel(&labelPublishServerExternalPort);
472488
renderer.renderListBox(&listBoxServerPort);
@@ -498,10 +514,14 @@ void MenuStateOptionsNetwork::render() {
498514
void MenuStateOptionsNetwork::saveConfig() {
499515
Config &config = Config::getInstance();
500516
Lang &lang = Lang::getInstance();
501-
setActiveInputLable(NULL);
517+
this->setActiveInputLabel(NULL);
502518

503519
lang.loadGameStrings(config.getString("Lang"));
504520

521+
if (labelServerBindIp.getText().length() >= 0) {
522+
config.setString("ServerBindAddress", labelServerBindIp.getText());
523+
}
524+
505525
config.setString("PortServer", listBoxServerPort.getSelectedItem());
506526
config.setInt("FTPServerPort", config.getInt("PortServer") + 1);
507527
config.setBool("EnableFTPXfer", checkBoxEnableFTP.getValue());
@@ -520,7 +540,18 @@ void MenuStateOptionsNetwork::saveConfig() {
520540
console.addLine(lang.getString("SettingsSaved"));
521541
}
522542

523-
void MenuStateOptionsNetwork::setActiveInputLable(GraphicLabel *newLable) {}
543+
bool MenuStateOptionsNetwork::textInput(std::string text) {
544+
if (activeInputLabel != NULL) {
545+
if (&labelServerBindIp == activeInputLabel) {
546+
return textInputEditLabel(text, &activeInputLabel);
547+
}
548+
}
549+
return false;
550+
}
551+
552+
void MenuStateOptionsNetwork::setActiveInputLabel(GraphicLabel *newLabel) {
553+
MenuState::setActiveInputLabel(newLabel, &activeInputLabel);
554+
}
524555

525556
} // namespace Game
526557
} // namespace Glest

source/glest_game/menu/menu_state_options_network.h

+7-3
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,10 @@ class MenuStateOptionsNetwork : public MenuState {
3737
int mainMessageBoxState;
3838

3939
GraphicLabel labelExternalPort;
40+
GraphicLabel labelServerBindIp;
41+
GraphicLabel labelServerBindIpLabel;
4042
GraphicLabel labelServerPortLabel;
43+
GraphicLabel *activeInputLabel;
4144

4245
GraphicLabel labelPublishServerExternalPort;
4346
GraphicListBox listBoxServerPort;
@@ -73,15 +76,16 @@ class MenuStateOptionsNetwork : public MenuState {
7376
void mouseDoubleClick(int x, int y, MouseButton mouseButton) {};
7477
void mouseMove(int x, int y, const MouseState *mouseState);
7578
void render();
76-
// virtual void keyDown(SDL_KeyboardEvent key);
79+
virtual bool textInput(std::string text);
80+
virtual void keyDown(SDL_KeyboardEvent key);
7781
virtual void keyPress(SDL_KeyboardEvent c);
78-
// virtual bool isInSpecialKeyCaptureEvent();
82+
// virtual bool isInSpecialKeyCaptureEvent();
7983

8084
virtual void reloadUI();
8185

8286
private:
8387
void saveConfig();
84-
void setActiveInputLable(GraphicLabel *newLable);
88+
void setActiveInputLabel(GraphicLabel *newLabel);
8589
// void showMessageBox(const string &text, const string &header, bool toggle);
8690
};
8791

source/glest_game/network/server_interface.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,8 @@ ServerInterface::ServerInterface(
158158
extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__);
159159

160160
serverSocket.setBlock(false);
161+
serverSocket.setBindAddress(
162+
Config::getInstance().getString("ServerBindAddress", ""));
161163
serverSocket.setBindPort(Config::getInstance().getInt(
162164
"PortServer", intToStr(GameConstants::serverPort).c_str()));
163165

source/shared_lib/include/platform/posix/socket.h

+2
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ class ServerSocket : public Socket, public UPNPInitInterface {
281281
bool portBound;
282282
int boundPort;
283283
string bindSpecificAddress;
284+
string bindAddress;
284285

285286
static int externalPort;
286287
static int ftpServerPort;
@@ -311,6 +312,7 @@ class ServerSocket : public Socket, public UPNPInitInterface {
311312
void clearBlockedIPAddress();
312313
bool hasBlockedIPAddresses() const;
313314

315+
void setBindAddress(string address) { bindAddress = address; }
314316
void setBindPort(int port) { boundPort = port; }
315317
int getBindPort() const { return boundPort; }
316318
bool isPortBound() const { return portBound; }

source/shared_lib/include/platform/sdl/platform_main.h

+5-8
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ const char *GAME_ARGS[] = {"--help",
3434
"--headless-server-status",
3535
"--server-title",
3636
"--use-ports",
37-
37+
"--bind-address",
3838
"--load-scenario",
3939
"--load-mod",
4040
"--preview-map",
@@ -100,10 +100,7 @@ const char *GAME_ARGS[] = {"--help",
100100
"--steam",
101101
"--steam-debug",
102102
"--steam-reset-stats",
103-
104-
"--verbose"
105-
106-
};
103+
"--verbose"};
107104

108105
enum GAME_ARG_TYPE {
109106
GAME_ARG_HELP = 0,
@@ -118,7 +115,7 @@ enum GAME_ARG_TYPE {
118115
GAME_ARG_MASTERSERVER_STATUS,
119116
GAME_ARG_SERVER_TITLE,
120117
GAME_ARG_USE_PORTS,
121-
118+
GAME_ARG_SERVER_BIND_ADDRESS,
122119
GAME_ARG_LOADSCENARIO,
123120
GAME_ARG_MOD,
124121
GAME_ARG_PREVIEW_MAP,
@@ -256,7 +253,8 @@ void printParameterHelp(const char *argv0, bool foundInvalidArgs) {
256253
"LAN host you may");
257254
printf("\n\n \t use: %s=auto-connect",
258255
GAME_ARGS[GAME_ARG_CONNECT]);
259-
256+
printf("\n\n%s=x \tBind game server to a specific IP address.\n",
257+
GAME_ARGS[GAME_ARG_SERVER_BIND_ADDRESS]);
260258
printf("\n\n%s=x \tAuto connect to host server at IP or hostname x.",
261259
GAME_ARGS[GAME_ARG_CLIENT]);
262260
printf(
@@ -732,7 +730,6 @@ void printParameterHelp(const char *argv0, bool foundInvalidArgs) {
732730

733731
printf("\n\n%s=x=y ", GAME_ARGS[GAME_ARG_STEAM]);
734732
printf("\n\n \tRun with Steam Client Integration.");
735-
736733
printf("\n\n%s \t\tDisplays verbose information in the console.",
737734
GAME_ARGS[GAME_ARG_VERBOSE_MODE]);
738735
printf("\n\n");

source/shared_lib/sources/platform/posix/socket.cpp

+20-5
Original file line numberDiff line numberDiff line change
@@ -3099,14 +3099,30 @@ void ServerSocket::bind(int port) {
30993099
setBlock(false);
31003100
}
31013101

3102+
char szBuf[BUFSIZ] = {};
31023103
// sockaddr structure
3103-
sockaddr_in addr;
3104+
sockaddr_in addr = {};
31043105
addr.sin_family = AF_INET;
31053106
if (this->bindSpecificAddress != "") {
31063107
addr.sin_addr.s_addr = inet_addr(this->bindSpecificAddress.c_str());
31073108
} else {
3108-
addr.sin_addr.s_addr = INADDR_ANY;
3109+
if (this->bindAddress.empty()) {
3110+
addr.sin_addr.s_addr = INADDR_ANY;
3111+
} else {
3112+
int res = inet_pton(AF_INET, this->bindAddress.c_str(), &addr.sin_addr);
3113+
3114+
if (res <= 0) {
3115+
if (res == 0) {
3116+
snprintf(szBuf, sizeof szBuf, "%s: Invalid network address\n",
3117+
this->bindAddress.c_str());
3118+
} else {
3119+
snprintf(szBuf, sizeof szBuf, "inet_pton: %s\n", strerror(errno));
3120+
}
3121+
throwException(szBuf);
3122+
}
3123+
}
31093124
}
3125+
31103126
addr.sin_port = htons(port);
31113127
addr.sin_zero[0] = 0;
31123128

@@ -3122,17 +3138,16 @@ void ServerSocket::bind(int port) {
31223138

31233139
int err = ::bind(sock, reinterpret_cast<sockaddr *>(&addr), sizeof(addr));
31243140
if (err < 0) {
3125-
char szBuf[8096] = "";
31263141
snprintf(
3127-
szBuf, 8096,
3142+
szBuf, sizeof szBuf,
31283143
"In [%s::%s] Error binding socket sock = " PLATFORM_SOCKET_FORMAT_TYPE
31293144
", address [%s] port = %d err = %d, error = %s opt_result = %d\n",
31303145
__FILE__, __FUNCTION__, sock, this->bindSpecificAddress.c_str(), port,
31313146
err, getLastSocketErrorFormattedText().c_str(), opt_result);
31323147
if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled)
31333148
SystemFlags::OutputDebug(SystemFlags::debugNetwork, "%s", szBuf);
31343149

3135-
snprintf(szBuf, 8096,
3150+
snprintf(szBuf, sizeof szBuf,
31363151
"Error binding socket sock = " PLATFORM_SOCKET_FORMAT_TYPE
31373152
", address [%s] port = %d err = %d, error = %s\n",
31383153
sock, this->bindSpecificAddress.c_str(), port, err,

0 commit comments

Comments
 (0)