mirror of
https://github.com/smartcmd/MinecraftConsoles.git
synced 2026-08-20 09:57:09 +00:00
Merge 0b9f676399 into d3412aaae7
This commit is contained in:
commit
fa395a4342
|
|
@ -918,7 +918,11 @@ void CPlatformNetworkManagerStub::SearchForGames()
|
||||||
info->data.isJoinable = true;
|
info->data.isJoinable = true;
|
||||||
strncpy_s(info->data.hostIP, sizeof(info->data.hostIP), ipBuf, _TRUNCATE);
|
strncpy_s(info->data.hostIP, sizeof(info->data.hostIP), ipBuf, _TRUNCATE);
|
||||||
info->data.hostPort = port;
|
info->data.hostPort = port;
|
||||||
info->sessionId = static_cast<uint64_t>(inet_addr(ipBuf)) | static_cast<uint64_t>(port) << 32;
|
|
||||||
|
//Hash IP so IPv4 and 6 both are a valid sess id
|
||||||
|
uint64_t ipHash = (uint64_t)std::hash<std::string>{}(ipBuf);
|
||||||
|
info->sessionId = (SessionID)(ipHash ^ (static_cast<uint64_t>(port << 32)));
|
||||||
|
|
||||||
friendsSessions[0].push_back(info);
|
friendsSessions[0].push_back(info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -230,6 +230,21 @@ void WinsockNetLayer::Shutdown()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool WinsockNetLayer::IsNumericAddress(const char* addr)
|
||||||
|
{
|
||||||
|
if (addr == nullptr)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
in6_addr buf{};
|
||||||
|
if (inet_pton(AF_INET6, addr, &buf) == 1)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (inet_pton(AF_INET, addr, &buf) == 1)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool WinsockNetLayer::HostGame(int port, const char* bindIp)
|
bool WinsockNetLayer::HostGame(int port, const char* bindIp)
|
||||||
{
|
{
|
||||||
if (!s_initialized && !Initialize()) return false;
|
if (!s_initialized && !Initialize()) return false;
|
||||||
|
|
@ -248,18 +263,26 @@ bool WinsockNetLayer::HostGame(int port, const char* bindIp)
|
||||||
s_smallIdToSocket[i] = INVALID_SOCKET;
|
s_smallIdToSocket[i] = INVALID_SOCKET;
|
||||||
LeaveCriticalSection(&s_smallIdToSocketLock);
|
LeaveCriticalSection(&s_smallIdToSocketLock);
|
||||||
|
|
||||||
struct addrinfo hints = {};
|
|
||||||
struct addrinfo* result = nullptr;
|
|
||||||
|
|
||||||
hints.ai_family = AF_INET;
|
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
|
||||||
hints.ai_protocol = IPPROTO_TCP;
|
|
||||||
hints.ai_flags = (bindIp == nullptr || bindIp[0] == 0) ? AI_PASSIVE : 0;
|
|
||||||
|
|
||||||
char portStr[16];
|
char portStr[16];
|
||||||
sprintf_s(portStr, "%d", port);
|
sprintf_s(portStr, "%d", port);
|
||||||
|
const char* resolvedBindIp = (bindIp != NULL && bindIp[0] != 0) ? bindIp : NULL;
|
||||||
|
|
||||||
const char* resolvedBindIp = (bindIp != nullptr && bindIp[0] != 0) ? bindIp : nullptr;
|
struct addrinfo hints = {};
|
||||||
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
hints.ai_protocol = IPPROTO_TCP;
|
||||||
|
|
||||||
|
if (resolvedBindIp == NULL)
|
||||||
|
{
|
||||||
|
hints.ai_family = AF_INET6;
|
||||||
|
hints.ai_flags = AI_PASSIVE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hints.ai_family = AF_UNSPEC;
|
||||||
|
hints.ai_flags = IsNumericAddress(resolvedBindIp) ? AI_NUMERICHOST : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct addrinfo* result = NULL;
|
||||||
int iResult = getaddrinfo(resolvedBindIp, portStr, &hints, &result);
|
int iResult = getaddrinfo(resolvedBindIp, portStr, &hints, &result);
|
||||||
if (iResult != 0)
|
if (iResult != 0)
|
||||||
{
|
{
|
||||||
|
|
@ -278,8 +301,14 @@ bool WinsockNetLayer::HostGame(int port, const char* bindIp)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int opt = 1;
|
if (result->ai_family == AF_INET6)
|
||||||
setsockopt(s_listenSocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&opt, sizeof(opt));
|
{
|
||||||
|
DWORD ipv6only = 0;
|
||||||
|
if (setsockopt(s_listenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&ipv6only, sizeof(ipv6only)) == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
app.DebugPrintf("setsockopt() failed: %d\n", WSAGetLastError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
iResult = ::bind(s_listenSocket, result->ai_addr, static_cast<int>(result->ai_addrlen));
|
iResult = ::bind(s_listenSocket, result->ai_addr, static_cast<int>(result->ai_addrlen));
|
||||||
freeaddrinfo(result);
|
freeaddrinfo(result);
|
||||||
|
|
@ -340,7 +369,12 @@ bool WinsockNetLayer::JoinGame(const char* ip, int port)
|
||||||
struct addrinfo hints = {};
|
struct addrinfo hints = {};
|
||||||
struct addrinfo* result = nullptr;
|
struct addrinfo* result = nullptr;
|
||||||
|
|
||||||
hints.ai_family = AF_INET;
|
if (IsNumericAddress(ip))
|
||||||
|
hints.ai_flags = AI_NUMERICHOST;
|
||||||
|
else
|
||||||
|
hints.ai_flags = 0;
|
||||||
|
|
||||||
|
hints.ai_family = AF_UNSPEC;
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
hints.ai_protocol = IPPROTO_TCP;
|
hints.ai_protocol = IPPROTO_TCP;
|
||||||
|
|
||||||
|
|
@ -755,7 +789,7 @@ static bool RecvExact(SOCKET sock, BYTE* buf, int len)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(MINECRAFT_SERVER_BUILD)
|
#if defined(MINECRAFT_SERVER_BUILD)
|
||||||
static bool TryGetNumericRemoteIp(const sockaddr_in &remoteAddress, std::string *outIp)
|
static bool TryGetNumericRemoteIp(const sockaddr_storage& remoteAddress, int remoteAddressLength, std::string* outIp)
|
||||||
{
|
{
|
||||||
if (outIp == nullptr)
|
if (outIp == nullptr)
|
||||||
{
|
{
|
||||||
|
|
@ -763,14 +797,17 @@ static bool TryGetNumericRemoteIp(const sockaddr_in &remoteAddress, std::string
|
||||||
}
|
}
|
||||||
|
|
||||||
outIp->clear();
|
outIp->clear();
|
||||||
char ipBuffer[64] = {};
|
char host[NI_MAXHOST] = {};
|
||||||
const char *ip = inet_ntop(AF_INET, (void *)&remoteAddress.sin_addr, ipBuffer, sizeof(ipBuffer));
|
if (getnameinfo((const sockaddr*)&remoteAddress, remoteAddressLength, host, sizeof(host), nullptr, 0, NI_NUMERICHOST) != 0)
|
||||||
if (ip == nullptr || ip[0] == 0)
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (host[0] == 0)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
*outIp = ip;
|
*outIp = host;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -809,7 +846,7 @@ DWORD WINAPI WinsockNetLayer::AcceptThreadProc(LPVOID param)
|
||||||
{
|
{
|
||||||
while (s_active)
|
while (s_active)
|
||||||
{
|
{
|
||||||
sockaddr_in remoteAddress;
|
sockaddr_storage remoteAddress;
|
||||||
ZeroMemory(&remoteAddress, sizeof(remoteAddress));
|
ZeroMemory(&remoteAddress, sizeof(remoteAddress));
|
||||||
int remoteAddressLength = sizeof(remoteAddress);
|
int remoteAddressLength = sizeof(remoteAddress);
|
||||||
SOCKET clientSocket = accept(s_listenSocket, (sockaddr*)&remoteAddress, &remoteAddressLength);
|
SOCKET clientSocket = accept(s_listenSocket, (sockaddr*)&remoteAddress, &remoteAddressLength);
|
||||||
|
|
@ -825,7 +862,7 @@ DWORD WINAPI WinsockNetLayer::AcceptThreadProc(LPVOID param)
|
||||||
|
|
||||||
#if defined(MINECRAFT_SERVER_BUILD)
|
#if defined(MINECRAFT_SERVER_BUILD)
|
||||||
std::string remoteIp;
|
std::string remoteIp;
|
||||||
const bool hasRemoteIp = TryGetNumericRemoteIp(remoteAddress, &remoteIp);
|
const bool hasRemoteIp = TryGetNumericRemoteIp(remoteAddress, remoteAddressLength, &remoteIp);
|
||||||
const char *remoteIpForLog = hasRemoteIp ? remoteIp.c_str() : "unknown";
|
const char *remoteIpForLog = hasRemoteIp ? remoteIp.c_str() : "unknown";
|
||||||
if (g_Win64DedicatedServer)
|
if (g_Win64DedicatedServer)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -67,8 +67,9 @@ class WinsockNetLayer
|
||||||
public:
|
public:
|
||||||
static bool Initialize();
|
static bool Initialize();
|
||||||
static void Shutdown();
|
static void Shutdown();
|
||||||
|
|
||||||
static bool HostGame(int port, const char* bindIp = nullptr);
|
static bool IsNumericAddress(const char* addr);
|
||||||
|
static bool HostGame(int port, const char* bindIp = NULL);
|
||||||
static bool JoinGame(const char* ip, int port);
|
static bool JoinGame(const char* ip, int port);
|
||||||
|
|
||||||
enum eJoinState
|
enum eJoinState
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ static const ServerPropertyDefault kServerPropertyDefaults[] =
|
||||||
{ "motd", "A Minecraft Server" },
|
{ "motd", "A Minecraft Server" },
|
||||||
{ "natural-regeneration", "true" },
|
{ "natural-regeneration", "true" },
|
||||||
{ "pvp", "true" },
|
{ "pvp", "true" },
|
||||||
{ "server-ip", "0.0.0.0" },
|
{ "server-ip", "::" },
|
||||||
{ "server-name", "DedicatedServer" },
|
{ "server-name", "DedicatedServer" },
|
||||||
{ "server-port", "25565" },
|
{ "server-port", "25565" },
|
||||||
{ "white-list", "false" },
|
{ "white-list", "false" },
|
||||||
|
|
@ -815,7 +815,7 @@ ServerPropertiesConfig LoadServerPropertiesConfig()
|
||||||
config.worldSaveId = worldSaveId;
|
config.worldSaveId = worldSaveId;
|
||||||
|
|
||||||
config.serverPort = ReadNormalizedIntProperty(&merged, "server-port", kDefaultServerPort, 1, 65535, &shouldWrite);
|
config.serverPort = ReadNormalizedIntProperty(&merged, "server-port", kDefaultServerPort, 1, 65535, &shouldWrite);
|
||||||
config.serverIp = ReadNormalizedStringProperty(&merged, "server-ip", "0.0.0.0", 255, &shouldWrite);
|
config.serverIp = ReadNormalizedStringProperty(&merged, "server-ip", "::", 255, &shouldWrite);
|
||||||
config.lanAdvertise = ReadNormalizedBoolProperty(&merged, kLanAdvertisePropertyKey, false, &shouldWrite);
|
config.lanAdvertise = ReadNormalizedBoolProperty(&merged, kLanAdvertisePropertyKey, false, &shouldWrite);
|
||||||
config.whiteListEnabled = ReadNormalizedBoolProperty(&merged, "white-list", false, &shouldWrite);
|
config.whiteListEnabled = ReadNormalizedBoolProperty(&merged, "white-list", false, &shouldWrite);
|
||||||
config.serverName = ReadNormalizedStringProperty(&merged, "server-name", "DedicatedServer", 16, &shouldWrite);
|
config.serverName = ReadNormalizedStringProperty(&merged, "server-name", "DedicatedServer", 16, &shouldWrite);
|
||||||
|
|
|
||||||
|
|
@ -297,7 +297,7 @@ static void ApplyServerPropertiesToDedicatedConfig(const ServerPropertiesConfig
|
||||||
strncpy_s(
|
strncpy_s(
|
||||||
config->bindIP,
|
config->bindIP,
|
||||||
sizeof(config->bindIP),
|
sizeof(config->bindIP),
|
||||||
serverProperties.serverIp.empty() ? "0.0.0.0" : serverProperties.serverIp.c_str(),
|
serverProperties.serverIp.empty() ? "::" : serverProperties.serverIp.c_str(),
|
||||||
_TRUNCATE);
|
_TRUNCATE);
|
||||||
strncpy_s(
|
strncpy_s(
|
||||||
config->name,
|
config->name,
|
||||||
|
|
@ -351,7 +351,7 @@ int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
DedicatedServerConfig config;
|
DedicatedServerConfig config;
|
||||||
config.port = WIN64_NET_DEFAULT_PORT;
|
config.port = WIN64_NET_DEFAULT_PORT;
|
||||||
strncpy_s(config.bindIP, sizeof(config.bindIP), "0.0.0.0", _TRUNCATE);
|
strncpy_s(config.bindIP, sizeof(config.bindIP), "::", _TRUNCATE);
|
||||||
strncpy_s(config.name, sizeof(config.name), "DedicatedServer", _TRUNCATE);
|
strncpy_s(config.name, sizeof(config.name), "DedicatedServer", _TRUNCATE);
|
||||||
config.maxPlayers = MINECRAFT_NET_MAX_PLAYERS;
|
config.maxPlayers = MINECRAFT_NET_MAX_PLAYERS;
|
||||||
config.worldSize = e_worldSize_Classic;
|
config.worldSize = e_worldSize_Classic;
|
||||||
|
|
@ -616,7 +616,13 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
LogStartupStep("server startup complete");
|
LogStartupStep("server startup complete");
|
||||||
LogInfof("startup", "Dedicated server listening on %s:%d", g_Win64MultiplayerIP, g_Win64MultiplayerPort);
|
|
||||||
|
const std::string displayIp = strchr(g_Win64MultiplayerIP, ':')
|
||||||
|
? "[" + std::string(g_Win64MultiplayerIP) + "]" //ipv6 address will always have a :
|
||||||
|
: g_Win64MultiplayerIP;
|
||||||
|
|
||||||
|
LogInfof("startup", "Dedicated server listening on %s:%d", displayIp.c_str(), g_Win64MultiplayerPort);
|
||||||
|
|
||||||
if (worldBootstrap.status == eWorldBootstrap_CreatedNew && !IsShutdownRequested() && !app.m_bShutdown)
|
if (worldBootstrap.status == eWorldBootstrap_CreatedNew && !IsShutdownRequested() && !app.m_bShutdown)
|
||||||
{
|
{
|
||||||
// Windows64 suppresses saveToDisc right after new world creation
|
// Windows64 suppresses saveToDisc right after new world creation
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ SERVER_DIR="/srv/mc"
|
||||||
SERVER_EXE="Minecraft.Server.exe"
|
SERVER_EXE="Minecraft.Server.exe"
|
||||||
# ip & port are fixed since they run inside the container
|
# ip & port are fixed since they run inside the container
|
||||||
SERVER_PORT="25565"
|
SERVER_PORT="25565"
|
||||||
SERVER_BIND_IP="0.0.0.0"
|
SERVER_BIND_IP="::"
|
||||||
|
|
||||||
PERSIST_DIR="/srv/persist"
|
PERSIST_DIR="/srv/persist"
|
||||||
WINE_CMD=""
|
WINE_CMD=""
|
||||||
|
|
@ -163,5 +163,11 @@ args=(
|
||||||
-bind "${SERVER_BIND_IP}"
|
-bind "${SERVER_BIND_IP}"
|
||||||
)
|
)
|
||||||
|
|
||||||
echo "[info] Starting ${SERVER_EXE} on ${SERVER_BIND_IP}:${SERVER_PORT}"
|
if [[ "$SERVER_BIND_IP" == *:* ]]; then
|
||||||
|
display_ip="[${SERVER_BIND_IP}]"
|
||||||
|
else
|
||||||
|
display_ip="$SERVER_BIND_IP"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[info] Starting ${SERVER_EXE} on ${display_ip}:${SERVER_PORT}"
|
||||||
exec "${WINE_CMD}" "${SERVER_EXE}" "${args[@]}"
|
exec "${WINE_CMD}" "${SERVER_EXE}" "${args[@]}"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue