mirror of
https://github.com/smartcmd/MinecraftConsoles.git
synced 2026-05-09 00:24:15 +00:00
Replace binary servers.db with text-based servers.txt (name:ip:port)
This commit is contained in:
@@ -811,54 +811,45 @@ void CPlatformNetworkManagerStub::SearchForGames()
|
|||||||
friendsSessions[0].push_back(info);
|
friendsSessions[0].push_back(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::FILE* file = std::fopen("servers.db", "rb");
|
std::FILE* file = std::fopen("servers.txt", "r");
|
||||||
|
|
||||||
if (file) {
|
if (file) {
|
||||||
char magic[4] = {};
|
char line[512];
|
||||||
if (std::fread(magic, 1, 4, file) == 4 && memcmp(magic, "MCSV", 4) == 0)
|
while (std::fgets(line, sizeof(line), file))
|
||||||
{
|
{
|
||||||
uint32_t version = 0, count = 0;
|
int l = (int)strlen(line);
|
||||||
std::fread(&version, sizeof(uint32_t), 1, file);
|
while (l > 0 && (line[l - 1] == '\n' || line[l - 1] == '\r' || line[l - 1] == ' '))
|
||||||
std::fread(&count, sizeof(uint32_t), 1, file);
|
line[--l] = '\0';
|
||||||
|
if (l == 0) continue;
|
||||||
|
|
||||||
if (version == 1)
|
// Format: name:ip:port
|
||||||
{
|
char* lastColon = strrchr(line, ':');
|
||||||
for (uint32_t s = 0; s < count; s++)
|
if (!lastColon) continue;
|
||||||
{
|
*lastColon = '\0';
|
||||||
uint16_t ipLen = 0, port = 0, nameLen = 0;
|
uint16_t port = (uint16_t)atoi(lastColon + 1);
|
||||||
if (std::fread(&ipLen, sizeof(uint16_t), 1, file) != 1) break;
|
|
||||||
if (ipLen == 0 || ipLen > 256) break;
|
|
||||||
|
|
||||||
char ipBuf[257] = {};
|
char* secondColon = strrchr(line, ':');
|
||||||
if (std::fread(ipBuf, 1, ipLen, file) != ipLen) break;
|
if (!secondColon) continue;
|
||||||
|
*secondColon = '\0';
|
||||||
|
char* ipBuf = secondColon + 1;
|
||||||
|
char* nameBuf = line;
|
||||||
|
|
||||||
if (std::fread(&port, sizeof(uint16_t), 1, file) != 1) break;
|
if (port == 0 || strlen(ipBuf) == 0) continue;
|
||||||
|
|
||||||
if (std::fread(&nameLen, sizeof(uint16_t), 1, file) != 1) break;
|
wstring wName = convStringToWstring(nameBuf);
|
||||||
if (nameLen > 256) break;
|
|
||||||
|
|
||||||
char nameBuf[257] = {};
|
FriendSessionInfo* info = new FriendSessionInfo();
|
||||||
if (nameLen > 0)
|
size_t nLen = wName.length();
|
||||||
{
|
info->displayLabel = new wchar_t[nLen + 1];
|
||||||
if (std::fread(nameBuf, 1, nameLen, file) != nameLen) break;
|
wcscpy_s(info->displayLabel, nLen + 1, wName.c_str());
|
||||||
}
|
info->displayLabelLength = (unsigned char)nLen;
|
||||||
|
info->displayLabelViewableStartIndex = 0;
|
||||||
wstring wName = convStringToWstring(nameBuf);
|
info->data.isReadyToJoin = true;
|
||||||
|
info->data.isJoinable = true;
|
||||||
FriendSessionInfo* info = new FriendSessionInfo();
|
strncpy_s(info->data.hostIP, sizeof(info->data.hostIP), ipBuf, _TRUNCATE);
|
||||||
size_t nLen = wName.length();
|
info->data.hostPort = port;
|
||||||
info->displayLabel = new wchar_t[nLen + 1];
|
info->sessionId = (SessionID)(static_cast<uint64_t>(inet_addr(ipBuf)) | (static_cast<uint64_t>(port) << 32));
|
||||||
wcscpy_s(info->displayLabel, nLen + 1, wName.c_str());
|
friendsSessions[0].push_back(info);
|
||||||
info->displayLabelLength = (unsigned char)nLen;
|
|
||||||
info->displayLabelViewableStartIndex = 0;
|
|
||||||
info->data.isReadyToJoin = true;
|
|
||||||
info->data.isJoinable = true;
|
|
||||||
strncpy_s(info->data.hostIP, sizeof(info->data.hostIP), ipBuf, _TRUNCATE);
|
|
||||||
info->data.hostPort = port;
|
|
||||||
info->sessionId = (SessionID)(static_cast<uint64_t>(inet_addr(ipBuf)) | (static_cast<uint64_t>(port) << 32));
|
|
||||||
friendsSessions[0].push_back(info);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
std::fclose(file);
|
std::fclose(file);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -840,134 +840,100 @@ void UIScene_JoinMenu::UpdateServerInFile(const wstring& newIP, const wstring& n
|
|||||||
wcstombs(narrowNewPort, newPort.c_str(), sizeof(narrowNewPort) - 1);
|
wcstombs(narrowNewPort, newPort.c_str(), sizeof(narrowNewPort) - 1);
|
||||||
wcstombs(narrowNewName, newName.c_str(), sizeof(narrowNewName) - 1);
|
wcstombs(narrowNewName, newName.c_str(), sizeof(narrowNewName) - 1);
|
||||||
|
|
||||||
uint16_t newPortNum = (uint16_t)atoi(narrowNewPort);
|
struct ServerEntry { std::string ip; std::string port; std::string name; };
|
||||||
|
|
||||||
struct ServerEntry { std::string ip; uint16_t port; std::string name; };
|
|
||||||
std::vector<ServerEntry> entries;
|
std::vector<ServerEntry> entries;
|
||||||
|
|
||||||
FILE* file = fopen("servers.db", "rb");
|
FILE* file = fopen("servers.txt", "r");
|
||||||
if (file)
|
if (file)
|
||||||
{
|
{
|
||||||
char magic[4] = {};
|
char line[512];
|
||||||
if (fread(magic, 1, 4, file) == 4 && memcmp(magic, "MCSV", 4) == 0)
|
while (fgets(line, sizeof(line), file))
|
||||||
{
|
{
|
||||||
uint32_t version = 0, count = 0;
|
int l = (int)strlen(line);
|
||||||
fread(&version, sizeof(uint32_t), 1, file);
|
while (l > 0 && (line[l - 1] == '\n' || line[l - 1] == '\r' || line[l - 1] == ' '))
|
||||||
fread(&count, sizeof(uint32_t), 1, file);
|
line[--l] = '\0';
|
||||||
if (version == 1)
|
if (l == 0) continue;
|
||||||
{
|
|
||||||
for (uint32_t s = 0; s < count; s++)
|
char* lastColon = strrchr(line, ':');
|
||||||
{
|
if (!lastColon) continue;
|
||||||
uint16_t ipLen = 0, p = 0, nameLen = 0;
|
*lastColon = '\0';
|
||||||
if (fread(&ipLen, sizeof(uint16_t), 1, file) != 1) break;
|
std::string port(lastColon + 1);
|
||||||
if (ipLen == 0 || ipLen > 256) break;
|
|
||||||
char ipBuf[257] = {};
|
char* secondColon = strrchr(line, ':');
|
||||||
if (fread(ipBuf, 1, ipLen, file) != ipLen) break;
|
if (!secondColon) continue;
|
||||||
if (fread(&p, sizeof(uint16_t), 1, file) != 1) break;
|
*secondColon = '\0';
|
||||||
if (fread(&nameLen, sizeof(uint16_t), 1, file) != 1) break;
|
std::string ip(secondColon + 1);
|
||||||
if (nameLen > 256) break;
|
std::string name(line);
|
||||||
char nameBuf[257] = {};
|
|
||||||
if (nameLen > 0 && fread(nameBuf, 1, nameLen, file) != nameLen) break;
|
uint16_t portVal = (uint16_t)atoi(port.c_str());
|
||||||
entries.push_back({std::string(ipBuf), p, std::string(nameBuf)});
|
if (portVal == 0 || ip.empty()) continue;
|
||||||
}
|
|
||||||
}
|
entries.push_back({ip, port, name});
|
||||||
}
|
}
|
||||||
fclose(file);
|
fclose(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find and update the matching entry by original IP and port
|
|
||||||
int idx = m_serverIndex;
|
int idx = m_serverIndex;
|
||||||
if (idx >= 0 && idx < (int)entries.size())
|
if (idx >= 0 && idx < (int)entries.size())
|
||||||
{
|
{
|
||||||
entries[idx].ip = std::string(narrowNewIP);
|
entries[idx].ip = std::string(narrowNewIP);
|
||||||
entries[idx].port = newPortNum;
|
entries[idx].port = std::string(narrowNewPort);
|
||||||
entries[idx].name = std::string(narrowNewName);
|
entries[idx].name = std::string(narrowNewName);
|
||||||
}
|
}
|
||||||
|
|
||||||
file = fopen("servers.db", "wb");
|
file = fopen("servers.txt", "w");
|
||||||
if (file)
|
if (file)
|
||||||
{
|
{
|
||||||
fwrite("MCSV", 1, 4, file);
|
|
||||||
uint32_t version = 1;
|
|
||||||
uint32_t count = (uint32_t)entries.size();
|
|
||||||
fwrite(&version, sizeof(uint32_t), 1, file);
|
|
||||||
fwrite(&count, sizeof(uint32_t), 1, file);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < entries.size(); i++)
|
for (size_t i = 0; i < entries.size(); i++)
|
||||||
{
|
fprintf(file, "%s:%s:%s\n", entries[i].name.c_str(), entries[i].ip.c_str(), entries[i].port.c_str());
|
||||||
uint16_t ipLen = (uint16_t)entries[i].ip.length();
|
|
||||||
fwrite(&ipLen, sizeof(uint16_t), 1, file);
|
|
||||||
fwrite(entries[i].ip.c_str(), 1, ipLen, file);
|
|
||||||
fwrite(&entries[i].port, sizeof(uint16_t), 1, file);
|
|
||||||
uint16_t nameLen = (uint16_t)entries[i].name.length();
|
|
||||||
fwrite(&nameLen, sizeof(uint16_t), 1, file);
|
|
||||||
fwrite(entries[i].name.c_str(), 1, nameLen, file);
|
|
||||||
}
|
|
||||||
fclose(file);
|
fclose(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UIScene_JoinMenu::RemoveServerFromFile()
|
void UIScene_JoinMenu::RemoveServerFromFile()
|
||||||
{
|
{
|
||||||
struct ServerEntry { std::string ip; uint16_t port; std::string name; };
|
struct ServerEntry { std::string name; std::string ip; std::string port; };
|
||||||
std::vector<ServerEntry> entries;
|
std::vector<ServerEntry> entries;
|
||||||
|
|
||||||
FILE* file = fopen("servers.db", "rb");
|
FILE* file = fopen("servers.txt", "r");
|
||||||
if (file)
|
if (file)
|
||||||
{
|
{
|
||||||
char magic[4] = {};
|
char line[512];
|
||||||
if (fread(magic, 1, 4, file) == 4 && memcmp(magic, "MCSV", 4) == 0)
|
while (fgets(line, sizeof(line), file))
|
||||||
{
|
{
|
||||||
uint32_t version = 0, count = 0;
|
int l = (int)strlen(line);
|
||||||
fread(&version, sizeof(uint32_t), 1, file);
|
while (l > 0 && (line[l - 1] == '\n' || line[l - 1] == '\r' || line[l - 1] == ' '))
|
||||||
fread(&count, sizeof(uint32_t), 1, file);
|
line[--l] = '\0';
|
||||||
if (version == 1)
|
if (l == 0) continue;
|
||||||
{
|
|
||||||
for (uint32_t s = 0; s < count; s++)
|
char* lastColon = strrchr(line, ':');
|
||||||
{
|
if (!lastColon) continue;
|
||||||
uint16_t ipLen = 0, p = 0, nameLen = 0;
|
*lastColon = '\0';
|
||||||
if (fread(&ipLen, sizeof(uint16_t), 1, file) != 1) break;
|
std::string port(lastColon + 1);
|
||||||
if (ipLen == 0 || ipLen > 256) break;
|
|
||||||
char ipBuf[257] = {};
|
char* secondColon = strrchr(line, ':');
|
||||||
if (fread(ipBuf, 1, ipLen, file) != ipLen) break;
|
if (!secondColon) continue;
|
||||||
if (fread(&p, sizeof(uint16_t), 1, file) != 1) break;
|
*secondColon = '\0';
|
||||||
if (fread(&nameLen, sizeof(uint16_t), 1, file) != 1) break;
|
std::string ip(secondColon + 1);
|
||||||
if (nameLen > 256) break;
|
std::string name(line);
|
||||||
char nameBuf[257] = {};
|
|
||||||
if (nameLen > 0 && fread(nameBuf, 1, nameLen, file) != nameLen) break;
|
uint16_t portVal = (uint16_t)atoi(port.c_str());
|
||||||
entries.push_back({std::string(ipBuf), p, std::string(nameBuf)});
|
if (portVal == 0 || ip.empty()) continue;
|
||||||
}
|
|
||||||
}
|
entries.push_back({name, ip, port});
|
||||||
}
|
}
|
||||||
fclose(file);
|
fclose(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the entry at m_serverIndex
|
|
||||||
int idx = m_serverIndex;
|
int idx = m_serverIndex;
|
||||||
if (idx >= 0 && idx < (int)entries.size())
|
if (idx >= 0 && idx < (int)entries.size())
|
||||||
{
|
|
||||||
entries.erase(entries.begin() + idx);
|
entries.erase(entries.begin() + idx);
|
||||||
}
|
|
||||||
|
|
||||||
file = fopen("servers.db", "wb");
|
file = fopen("servers.txt", "w");
|
||||||
if (file)
|
if (file)
|
||||||
{
|
{
|
||||||
fwrite("MCSV", 1, 4, file);
|
|
||||||
uint32_t version = 1;
|
|
||||||
uint32_t count = (uint32_t)entries.size();
|
|
||||||
fwrite(&version, sizeof(uint32_t), 1, file);
|
|
||||||
fwrite(&count, sizeof(uint32_t), 1, file);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < entries.size(); i++)
|
for (size_t i = 0; i < entries.size(); i++)
|
||||||
{
|
fprintf(file, "%s:%s:%s\n", entries[i].name.c_str(), entries[i].ip.c_str(), entries[i].port.c_str());
|
||||||
uint16_t ipLen = (uint16_t)entries[i].ip.length();
|
|
||||||
fwrite(&ipLen, sizeof(uint16_t), 1, file);
|
|
||||||
fwrite(entries[i].ip.c_str(), 1, ipLen, file);
|
|
||||||
fwrite(&entries[i].port, sizeof(uint16_t), 1, file);
|
|
||||||
uint16_t nameLen = (uint16_t)entries[i].name.length();
|
|
||||||
fwrite(&nameLen, sizeof(uint16_t), 1, file);
|
|
||||||
fwrite(entries[i].name.c_str(), 1, nameLen, file);
|
|
||||||
}
|
|
||||||
fclose(file);
|
fclose(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ private:
|
|||||||
bool m_friendInfoUpdatedERROR;
|
bool m_friendInfoUpdatedERROR;
|
||||||
|
|
||||||
#ifdef _WINDOWS64
|
#ifdef _WINDOWS64
|
||||||
int m_serverIndex; // Index in servers.db, -1 if not a saved server
|
int m_serverIndex; // Index in servers.txt, -1 if not a saved server
|
||||||
enum eEditServerPhase { eEditServer_Idle, eEditServer_IP, eEditServer_Port, eEditServer_Name };
|
enum eEditServerPhase { eEditServer_Idle, eEditServer_IP, eEditServer_Port, eEditServer_Name };
|
||||||
eEditServerPhase m_editServerPhase;
|
eEditServerPhase m_editServerPhase;
|
||||||
wstring m_editServerIP;
|
wstring m_editServerIP;
|
||||||
|
|||||||
@@ -1773,17 +1773,30 @@ void UIScene_LoadOrJoinMenu::CheckAndJoinGame(int gameIndex)
|
|||||||
{
|
{
|
||||||
|
|
||||||
int serverDbCount = 0;
|
int serverDbCount = 0;
|
||||||
FILE* dbFile = fopen("servers.db", "rb");
|
FILE* dbFile = fopen("servers.txt", "r");
|
||||||
if (dbFile)
|
if (dbFile)
|
||||||
{
|
{
|
||||||
char magic[4] = {};
|
char line[512];
|
||||||
if (fread(magic, 1, 4, dbFile) == 4 && memcmp(magic, "MCSV", 4) == 0)
|
while (fgets(line, sizeof(line), dbFile))
|
||||||
{
|
{
|
||||||
uint32_t version = 0, count = 0;
|
int l = (int)strlen(line);
|
||||||
fread(&version, sizeof(uint32_t), 1, dbFile);
|
while (l > 0 && (line[l - 1] == '\n' || line[l - 1] == '\r' || line[l - 1] == ' '))
|
||||||
fread(&count, sizeof(uint32_t), 1, dbFile);
|
line[--l] = '\0';
|
||||||
if (version == 1)
|
if (l == 0) continue;
|
||||||
serverDbCount = (int)count;
|
|
||||||
|
char* lastColon = strrchr(line, ':');
|
||||||
|
if (!lastColon) continue;
|
||||||
|
*lastColon = '\0';
|
||||||
|
uint16_t port = (uint16_t)atoi(lastColon + 1);
|
||||||
|
|
||||||
|
char* secondColon = strrchr(line, ':');
|
||||||
|
if (!secondColon) continue;
|
||||||
|
*secondColon = '\0';
|
||||||
|
char* ipBuf = secondColon + 1;
|
||||||
|
|
||||||
|
if (port == 0 || strlen(ipBuf) == 0) continue;
|
||||||
|
|
||||||
|
serverDbCount++;
|
||||||
}
|
}
|
||||||
fclose(dbFile);
|
fclose(dbFile);
|
||||||
}
|
}
|
||||||
@@ -4242,62 +4255,10 @@ void UIScene_LoadOrJoinMenu::AppendServerToFile(const wstring& ip, const wstring
|
|||||||
wcstombs(narrowPort, port.c_str(), sizeof(narrowPort) - 1);
|
wcstombs(narrowPort, port.c_str(), sizeof(narrowPort) - 1);
|
||||||
wcstombs(narrowName, name.c_str(), sizeof(narrowName) - 1);
|
wcstombs(narrowName, name.c_str(), sizeof(narrowName) - 1);
|
||||||
|
|
||||||
uint16_t portNum = (uint16_t)atoi(narrowPort);
|
FILE* file = fopen("servers.txt", "a");
|
||||||
|
|
||||||
struct ServerEntry { std::string ip; uint16_t port; std::string name; };
|
|
||||||
std::vector<ServerEntry> entries;
|
|
||||||
|
|
||||||
FILE* file = fopen("servers.db", "rb");
|
|
||||||
if (file)
|
if (file)
|
||||||
{
|
{
|
||||||
char magic[4] = {};
|
fprintf(file, "%s:%s:%s\n", narrowName, narrowIP, narrowPort);
|
||||||
if (fread(magic, 1, 4, file) == 4 && memcmp(magic, "MCSV", 4) == 0)
|
|
||||||
{
|
|
||||||
uint32_t version = 0, count = 0;
|
|
||||||
fread(&version, sizeof(uint32_t), 1, file);
|
|
||||||
fread(&count, sizeof(uint32_t), 1, file);
|
|
||||||
if (version == 1)
|
|
||||||
{
|
|
||||||
for (uint32_t s = 0; s < count; s++)
|
|
||||||
{
|
|
||||||
uint16_t ipLen = 0, p = 0, nameLen = 0;
|
|
||||||
if (fread(&ipLen, sizeof(uint16_t), 1, file) != 1) break;
|
|
||||||
if (ipLen == 0 || ipLen > 256) break;
|
|
||||||
char ipBuf[257] = {};
|
|
||||||
if (fread(ipBuf, 1, ipLen, file) != ipLen) break;
|
|
||||||
if (fread(&p, sizeof(uint16_t), 1, file) != 1) break;
|
|
||||||
if (fread(&nameLen, sizeof(uint16_t), 1, file) != 1) break;
|
|
||||||
if (nameLen > 256) break;
|
|
||||||
char nameBuf[257] = {};
|
|
||||||
if (nameLen > 0 && fread(nameBuf, 1, nameLen, file) != nameLen) break;
|
|
||||||
entries.push_back({std::string(ipBuf), p, std::string(nameBuf)});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fclose(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
entries.push_back({std::string(narrowIP), portNum, std::string(narrowName)});
|
|
||||||
|
|
||||||
file = fopen("servers.db", "wb");
|
|
||||||
if (file)
|
|
||||||
{
|
|
||||||
fwrite("MCSV", 1, 4, file);
|
|
||||||
uint32_t version = 1;
|
|
||||||
uint32_t count = (uint32_t)entries.size();
|
|
||||||
fwrite(&version, sizeof(uint32_t), 1, file);
|
|
||||||
fwrite(&count, sizeof(uint32_t), 1, file);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < entries.size(); i++)
|
|
||||||
{
|
|
||||||
uint16_t ipLen = (uint16_t)entries[i].ip.length();
|
|
||||||
fwrite(&ipLen, sizeof(uint16_t), 1, file);
|
|
||||||
fwrite(entries[i].ip.c_str(), 1, ipLen, file);
|
|
||||||
fwrite(&entries[i].port, sizeof(uint16_t), 1, file);
|
|
||||||
uint16_t nameLen = (uint16_t)entries[i].name.length();
|
|
||||||
fwrite(&nameLen, sizeof(uint16_t), 1, file);
|
|
||||||
fwrite(entries[i].name.c_str(), 1, nameLen, file);
|
|
||||||
}
|
|
||||||
fclose(file);
|
fclose(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -281,7 +281,7 @@ typedef struct _JoinMenuInitData
|
|||||||
FriendSessionInfo *selectedSession;
|
FriendSessionInfo *selectedSession;
|
||||||
int iPad;
|
int iPad;
|
||||||
#ifdef _WINDOWS64
|
#ifdef _WINDOWS64
|
||||||
int serverIndex; // Index of the server in servers.db, -1 if not a saved server
|
int serverIndex; // Index of the server in servers.txt, -1 if not a saved server
|
||||||
#endif
|
#endif
|
||||||
} JoinMenuInitData;
|
} JoinMenuInitData;
|
||||||
|
|
||||||
|
|||||||
@@ -1581,67 +1581,50 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
|
|||||||
|
|
||||||
MultiByteToWideChar(CP_ACP, 0, g_Win64Username, -1, g_Win64UsernameW, 17);
|
MultiByteToWideChar(CP_ACP, 0, g_Win64Username, -1, g_Win64UsernameW, 17);
|
||||||
|
|
||||||
// convert servers.txt to servers.db
|
// convert servers.db to servers.txt
|
||||||
if (GetFileAttributesA("servers.txt") != INVALID_FILE_ATTRIBUTES &&
|
if (GetFileAttributesA("servers.db") != INVALID_FILE_ATTRIBUTES &&
|
||||||
GetFileAttributesA("servers.db") == INVALID_FILE_ATTRIBUTES)
|
GetFileAttributesA("servers.txt") == INVALID_FILE_ATTRIBUTES)
|
||||||
{
|
{
|
||||||
FILE* txtFile = nullptr;
|
FILE* dbFile = nullptr;
|
||||||
if (fopen_s(&txtFile, "servers.txt", "r") == 0 && txtFile)
|
if (fopen_s(&dbFile, "servers.db", "rb") == 0 && dbFile)
|
||||||
{
|
{
|
||||||
struct MigEntry { std::string ip; uint16_t port; std::string name; };
|
struct MigEntry { std::string ip; uint16_t port; std::string name; };
|
||||||
std::vector<MigEntry> migEntries;
|
std::vector<MigEntry> migEntries;
|
||||||
char line[512];
|
|
||||||
|
|
||||||
while (fgets(line, sizeof(line), txtFile))
|
char magic[4] = {};
|
||||||
|
if (fread(magic, 1, 4, dbFile) == 4 && memcmp(magic, "MCSV", 4) == 0)
|
||||||
{
|
{
|
||||||
int l = (int)strlen(line);
|
uint32_t version = 0, count = 0;
|
||||||
while (l > 0 && (line[l - 1] == '\n' || line[l - 1] == '\r' || line[l - 1] == ' '))
|
fread(&version, sizeof(uint32_t), 1, dbFile);
|
||||||
line[--l] = '\0';
|
fread(&count, sizeof(uint32_t), 1, dbFile);
|
||||||
if (l == 0) continue;
|
if (version == 1)
|
||||||
|
|
||||||
std::string srvIP = line;
|
|
||||||
|
|
||||||
if (!fgets(line, sizeof(line), txtFile)) break;
|
|
||||||
l = (int)strlen(line);
|
|
||||||
while (l > 0 && (line[l - 1] == '\n' || line[l - 1] == '\r' || line[l - 1] == ' '))
|
|
||||||
line[--l] = '\0';
|
|
||||||
uint16_t srvPort = (uint16_t)atoi(line);
|
|
||||||
|
|
||||||
std::string srvName;
|
|
||||||
if (fgets(line, sizeof(line), txtFile))
|
|
||||||
{
|
{
|
||||||
l = (int)strlen(line);
|
for (uint32_t s = 0; s < count; s++)
|
||||||
while (l > 0 && (line[l - 1] == '\n' || line[l - 1] == '\r' || line[l - 1] == ' '))
|
{
|
||||||
line[--l] = '\0';
|
uint16_t ipLen = 0, p = 0, nameLen = 0;
|
||||||
srvName = line;
|
if (fread(&ipLen, sizeof(uint16_t), 1, dbFile) != 1) break;
|
||||||
|
if (ipLen == 0 || ipLen > 256) break;
|
||||||
|
char ipBuf[257] = {};
|
||||||
|
if (fread(ipBuf, 1, ipLen, dbFile) != ipLen) break;
|
||||||
|
if (fread(&p, sizeof(uint16_t), 1, dbFile) != 1) break;
|
||||||
|
if (fread(&nameLen, sizeof(uint16_t), 1, dbFile) != 1) break;
|
||||||
|
if (nameLen > 256) break;
|
||||||
|
char nameBuf[257] = {};
|
||||||
|
if (nameLen > 0 && fread(nameBuf, 1, nameLen, dbFile) != nameLen) break;
|
||||||
|
migEntries.push_back({std::string(ipBuf), p, std::string(nameBuf)});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!srvIP.empty() && srvPort > 0)
|
|
||||||
migEntries.push_back({srvIP, srvPort, srvName});
|
|
||||||
}
|
}
|
||||||
fclose(txtFile);
|
fclose(dbFile);
|
||||||
|
|
||||||
if (!migEntries.empty())
|
if (!migEntries.empty())
|
||||||
{
|
{
|
||||||
FILE* dbFile = nullptr;
|
FILE* txtFile = nullptr;
|
||||||
if (fopen_s(&dbFile, "servers.db", "wb") == 0 && dbFile)
|
if (fopen_s(&txtFile, "servers.txt", "w") == 0 && txtFile)
|
||||||
{
|
{
|
||||||
fwrite("MCSV", 1, 4, dbFile);
|
|
||||||
uint32_t ver = 1;
|
|
||||||
uint32_t cnt = (uint32_t)migEntries.size();
|
|
||||||
fwrite(&ver, sizeof(uint32_t), 1, dbFile);
|
|
||||||
fwrite(&cnt, sizeof(uint32_t), 1, dbFile);
|
|
||||||
for (size_t i = 0; i < migEntries.size(); i++)
|
for (size_t i = 0; i < migEntries.size(); i++)
|
||||||
{
|
fprintf(txtFile, "%s:%s:%u\n", migEntries[i].name.c_str(), migEntries[i].ip.c_str(), migEntries[i].port);
|
||||||
uint16_t ipLen = (uint16_t)migEntries[i].ip.length();
|
fclose(txtFile);
|
||||||
fwrite(&ipLen, sizeof(uint16_t), 1, dbFile);
|
|
||||||
fwrite(migEntries[i].ip.c_str(), 1, ipLen, dbFile);
|
|
||||||
fwrite(&migEntries[i].port, sizeof(uint16_t), 1, dbFile);
|
|
||||||
uint16_t nameLen = (uint16_t)migEntries[i].name.length();
|
|
||||||
fwrite(&nameLen, sizeof(uint16_t), 1, dbFile);
|
|
||||||
fwrite(migEntries[i].name.c_str(), 1, nameLen, dbFile);
|
|
||||||
}
|
|
||||||
fclose(dbFile);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
14
README.md
14
README.md
@@ -35,7 +35,7 @@ Basic LAN multiplayer is available on the Windows build
|
|||||||
- Other players on the same LAN can discover the session from the in-game Join Game menu
|
- Other players on the same LAN can discover the session from the in-game Join Game menu
|
||||||
- Game connections use TCP port `25565` by default
|
- Game connections use TCP port `25565` by default
|
||||||
- LAN discovery uses UDP port `25566`
|
- LAN discovery uses UDP port `25566`
|
||||||
- Add servers to your server list with `servers.txt` (temp solution)
|
- Add servers to your server list with `servers.txt`
|
||||||
- Rename yourself without losing data by keeping your `uid.dat`
|
- Rename yourself without losing data by keeping your `uid.dat`
|
||||||
|
|
||||||
Parts of this feature are based on code from [LCEMP](https://github.com/LCEMP/LCEMP) (thanks!)
|
Parts of this feature are based on code from [LCEMP](https://github.com/LCEMP/LCEMP) (thanks!)
|
||||||
@@ -44,19 +44,13 @@ Parts of this feature are based on code from [LCEMP](https://github.com/LCEMP/LC
|
|||||||
|
|
||||||
To add a server to your game, create the `servers.txt` file in the same directory as you have `Minecraft.Client.exe`. Inside, follow this format:
|
To add a server to your game, create the `servers.txt` file in the same directory as you have `Minecraft.Client.exe`. Inside, follow this format:
|
||||||
```
|
```
|
||||||
serverip.example.com
|
name:ip:port
|
||||||
25565
|
|
||||||
The name of your server in UI!
|
|
||||||
```
|
```
|
||||||
|
|
||||||
For example, here's a valid servers.txt
|
For example, here's a valid servers.txt
|
||||||
```
|
```
|
||||||
1.1.1.1
|
Cloudflare's Very Own LCE Server:1.1.1.1:25565
|
||||||
25565
|
Localhost Test Crap:127.0.0.1:25565
|
||||||
Cloudflare's Very Own LCE Server
|
|
||||||
127.0.0.1
|
|
||||||
25565
|
|
||||||
Localhost Test Crap
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Launch Arguments
|
### Launch Arguments
|
||||||
|
|||||||
Reference in New Issue
Block a user