request our own external address in the beginning so we can udp punch without help

This commit is contained in:
Tim Felgentreff 2020-11-26 16:19:55 +01:00
parent 63f6a41678
commit 83ef848156

View file

@ -728,7 +728,7 @@ public:
setPassword("");
}
void sendText(std::string txt) {
void sendText(std::string txt, bool silent = false) {
// C>S 0x0E SID_CHATCOMMAND
int pos = 0;
for (unsigned int pos = 0; pos < txt.size(); pos += 220) {
@ -740,7 +740,15 @@ public:
msg.serialize(text.c_str());
msg.flush(getTCPSocket());
}
showChat(username + ": " + txt);
if (!silent) {
showChat(username + ": " + txt);
}
}
void requestExternalAddress() {
// uses the /netinfo command to get which ip:port the server sees from us
sendText("/netinfo", true);
requestedAddress = true;
}
void requestExtraUserInfo(std::string username) {
@ -757,7 +765,9 @@ public:
}
void punchNAT(std::string username) {
sendText("/udppunch " + username);
if (externalAddress.isValid()) {
sendText("/whisper " + username + " /udppunch " + externalAddress.toString());
}
}
void refreshChannels() {
@ -1049,6 +1059,30 @@ public:
std::queue<std::string> *getInfo() { return &info; }
void showInfo(std::string arg) {
if (requestedAddress) {
// we have requested our external address from the server
DebugPrint("Requested Address Info: %s\n" _C_ arg.c_str());
if (arg.find("Server TCP: ") != std::string::npos || arg.find("Client TCP: ") != std::string::npos) {
// ignore
return;
}
if (arg.find("Client UDP: ") != std::string::npos) {
unsigned int a, b, c, d, ip, port;
unsigned char prefix[256]; // longer than any BNet message can be
int res = sscanf(arg.c_str(), "%s %s %d.%d.%d.%d:%d", prefix, prefix, &a, &b, &c, &d, &port);
if (res == 7 && a < 255 && b < 255 && c < 255 && d < 255 && port > 1024) {
ip = a | b << 8 | c << 16 | d << 24;
externalAddress = CHost(ip, port);
DebugPrint("My external address is %s\n" _C_ externalAddress.toString().c_str());
}
return;
}
if (arg.find("Game UDP: ") != std::string::npos) {
// this is the last line in the /netinfo response
requestedAddress = false;
return;
}
}
std::string infoStr = arg;
info.push(infoStr);
if (ShowInfo != NULL) {
@ -1243,6 +1277,9 @@ private:
bool hasPassword;
bool createAccount;
bool requestedAddress = false;
CHost externalAddress;
std::string lastError;
std::string currentChannel;
@ -1302,6 +1339,10 @@ public:
ctx->refreshGames();
}
if (ticks == 50) {
ctx->requestExternalAddress();
}
ticks++;
if (ctx->getTCPSocket()->HasDataToRead(0)) {
@ -1531,8 +1572,6 @@ class S2C_ENTERCHAT : public NetworkState {
}
ctx->requestExtraUserInfo(ctx->getUsername());
// send again
ctx->sendUdpConnectionInfo();
ctx->setState(new S2C_CHATEVENT());
}
@ -1691,18 +1730,6 @@ class S2C_LOGONRESPONSE2 : public NetworkState {
}
}
}
private:
void createAccount(Context *ctx) {
BNCSOutputStream msg(0x3d);
uint32_t *pw = ctx->getPassword1();
for (int i = 0; i < 20; i++) {
msg.serialize8(reinterpret_cast<uint8_t*>(pw)[i]);
}
msg.serialize(ctx->getUsername().c_str());
msg.flush(ctx->getTCPSocket());
ctx->setState(new S2C_CREATEACCOUNT2());
}
};
void C2S_LOGONRESPONSE2_OR_C2S_CREATEACCOUNT::doOneStep(Context *ctx) {