Support mc:// urls as command line argument

This commit is contained in:
UnknownShadow200 2024-06-26 23:30:04 +10:00
parent 6c3a9d7466
commit 4cb9e200ed
9 changed files with 66 additions and 36 deletions

View File

@ -84,7 +84,7 @@
9A89D58A27F802F600FF3F80 /* BlockPhysics.c in Sources */ = {isa = PBXBuildFile; fileRef = 9A89D4DB27F802F600FF3F80 /* BlockPhysics.c */; };
9A89D58B27F802F600FF3F80 /* Launcher.c in Sources */ = {isa = PBXBuildFile; fileRef = 9A89D4DD27F802F600FF3F80 /* Launcher.c */; };
9A89D58D27F802F600FF3F80 /* Options.c in Sources */ = {isa = PBXBuildFile; fileRef = 9A89D4E327F802F600FF3F80 /* Options.c */; };
9A89D58E27F802F600FF3F80 /* Window_SDL.c in Sources */ = {isa = PBXBuildFile; fileRef = 9A89D4E427F802F600FF3F80 /* Window_SDL.c */; };
9A89D58E27F802F600FF3F80 /* Window_SDL2.c in Sources */ = {isa = PBXBuildFile; fileRef = 9A89D4E427F802F600FF3F80 /* Window_SDL2.c */; };
9A89D58F27F802F600FF3F80 /* Audio.c in Sources */ = {isa = PBXBuildFile; fileRef = 9A89D4E727F802F600FF3F80 /* Audio.c */; };
9A89D59027F802F600FF3F80 /* Stream.c in Sources */ = {isa = PBXBuildFile; fileRef = 9A89D4E827F802F600FF3F80 /* Stream.c */; };
9A89D59127F802F600FF3F80 /* Vectors.c in Sources */ = {isa = PBXBuildFile; fileRef = 9A89D4E927F802F600FF3F80 /* Vectors.c */; };
@ -174,7 +174,7 @@
9A89D4DB27F802F600FF3F80 /* BlockPhysics.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = BlockPhysics.c; sourceTree = "<group>"; };
9A89D4DD27F802F600FF3F80 /* Launcher.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = Launcher.c; sourceTree = "<group>"; };
9A89D4E327F802F600FF3F80 /* Options.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = Options.c; sourceTree = "<group>"; };
9A89D4E427F802F600FF3F80 /* Window_SDL.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = Window_SDL.c; sourceTree = "<group>"; };
9A89D4E427F802F600FF3F80 /* Window_SDL2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = Window_SDL2.c; sourceTree = "<group>"; };
9A89D4E727F802F600FF3F80 /* Audio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = Audio.c; sourceTree = "<group>"; };
9A89D4E827F802F600FF3F80 /* Stream.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = Stream.c; sourceTree = "<group>"; };
9A89D4E927F802F600FF3F80 /* Vectors.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = Vectors.c; sourceTree = "<group>"; };
@ -297,7 +297,7 @@
9A89D4E927F802F600FF3F80 /* Vectors.c */,
9A89D37C27F802F500FF3F80 /* Vorbis.c */,
9A89D4EE27F802F600FF3F80 /* Widgets.c */,
9A89D4E427F802F600FF3F80 /* Window_SDL.c */,
9A89D4E427F802F600FF3F80 /* Window_SDL2.c */,
9A89D48727F802F600FF3F80 /* World.c */,
9A89D47F27F802F600FF3F80 /* interop_ios.m */,
);
@ -377,7 +377,7 @@
9A89D56C27F802F600FF3F80 /* _ftinit.c in Sources */,
9A89D58F27F802F600FF3F80 /* Audio.c in Sources */,
9A89D55227F802F600FF3F80 /* Logger.c in Sources */,
9A89D58E27F802F600FF3F80 /* Window_SDL.c in Sources */,
9A89D58E27F802F600FF3F80 /* Window_SDL2.c in Sources */,
9A89D4FF27F802F600FF3F80 /* Gui.c in Sources */,
9A89D55027F802F600FF3F80 /* Entity.c in Sources */,
9A89D58327F802F600FF3F80 /* EntityComponents.c in Sources */,

View File

@ -19,7 +19,7 @@
9A6C7C962C073E0C00676D27 /* Screens.c in Sources */ = {isa = PBXBuildFile; fileRef = 9A6C7BFD2C073DEE00676D27 /* Screens.c */; };
9A6C7C972C073E0C00676D27 /* SSL.c in Sources */ = {isa = PBXBuildFile; fileRef = 9A6C7BFE2C073DEE00676D27 /* SSL.c */; };
9A6C7C982C073E0C00676D27 /* LBackend_Android.c in Sources */ = {isa = PBXBuildFile; fileRef = 9A6C7BFF2C073DEE00676D27 /* LBackend_Android.c */; };
9A6C7C992C073E0C00676D27 /* Window_SDL.c in Sources */ = {isa = PBXBuildFile; fileRef = 9A6C7C002C073DEE00676D27 /* Window_SDL.c */; };
9A6C7C992C073E0C00676D27 /* Window_SDL2.c in Sources */ = {isa = PBXBuildFile; fileRef = 9A6C7C002C073DEE00676D27 /* Window_SDL2.c */; };
9A6C7C9A2C073E0C00676D27 /* Graphics_GL2.c in Sources */ = {isa = PBXBuildFile; fileRef = 9A6C7C012C073DEE00676D27 /* Graphics_GL2.c */; };
9A6C7C9B2C073E0C00676D27 /* Lighting.c in Sources */ = {isa = PBXBuildFile; fileRef = 9A6C7C022C073DEE00676D27 /* Lighting.c */; };
9A6C7C9C2C073E0C00676D27 /* EntityComponents.c in Sources */ = {isa = PBXBuildFile; fileRef = 9A6C7C042C073DEF00676D27 /* EntityComponents.c */; };
@ -135,7 +135,7 @@
9A6C7BFD2C073DEE00676D27 /* Screens.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Screens.c; path = "../../../../../../ClassiCube-master/src/Screens.c"; sourceTree = "<group>"; };
9A6C7BFE2C073DEE00676D27 /* SSL.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SSL.c; path = "../../../../../../ClassiCube-master/src/SSL.c"; sourceTree = "<group>"; };
9A6C7BFF2C073DEE00676D27 /* LBackend_Android.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = LBackend_Android.c; path = "../../../../../../ClassiCube-master/src/LBackend_Android.c"; sourceTree = "<group>"; };
9A6C7C002C073DEE00676D27 /* Window_SDL.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Window_SDL.c; path = "../../../../../../ClassiCube-master/src/Window_SDL.c"; sourceTree = "<group>"; };
9A6C7C002C073DEE00676D27 /* Window_SDL2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Window_SDL2.c; path = "../../../../../../ClassiCube-master/src/Window_SDL2.c"; sourceTree = "<group>"; };
9A6C7C012C073DEE00676D27 /* Graphics_GL2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Graphics_GL2.c; path = "../../../../../../ClassiCube-master/src/Graphics_GL2.c"; sourceTree = "<group>"; };
9A6C7C022C073DEE00676D27 /* Lighting.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Lighting.c; path = "../../../../../../ClassiCube-master/src/Lighting.c"; sourceTree = "<group>"; };
9A6C7C032C073DEF00676D27 /* Http.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Http.h; path = "../../../../../../ClassiCube-master/src/Http.h"; sourceTree = "<group>"; };
@ -466,7 +466,7 @@
9A6C7C0F2C073DF100676D27 /* Vorbis.h */,
9A6C7C662C073E0400676D27 /* Widgets.c */,
9A6C7C122C073DF100676D27 /* Widgets.h */,
9A6C7C002C073DEE00676D27 /* Window_SDL.c */,
9A6C7C002C073DEE00676D27 /* Window_SDL2.c */,
9A6C7C162C073DF200676D27 /* Window_SDL3.c */,
9A6C7C302C073DF600676D27 /* Window_Terminal.c */,
9A6C7C692C073E0400676D27 /* Window.h */,
@ -563,7 +563,7 @@
9A6C7CAB2C073E0C00676D27 /* _ftbase.c in Sources */,
9A6C7CB22C073E0C00676D27 /* MapRenderer.c in Sources */,
9A6C7C9B2C073E0C00676D27 /* Lighting.c in Sources */,
9A6C7C992C073E0C00676D27 /* Window_SDL.c in Sources */,
9A6C7C992C073E0C00676D27 /* Window_SDL2.c in Sources */,
9A6C7CBF2C073E0C00676D27 /* TouchUI.c in Sources */,
9A6C7CD32C073E0C00676D27 /* Http_Worker.c in Sources */,
9A6C7CD82C073E0C00676D27 /* Entity.c in Sources */,

View File

@ -462,54 +462,40 @@ LAYOUTS dc_lblStatus[] = { { ANCHOR_CENTRE, 0 }, { ANCHOR_CENTRE, 70 } };
static void DirectConnectScreen_UrlFilter(cc_string* str) {
static const cc_string prefix = String_FromConst("mc://");
cc_string parts[6];
if (!String_CaselessStarts(str, &prefix)) return;
/* mc://[ip:port]/[username]/[mppass] */
if (String_UNSAFE_Split(str, '/', parts, 6) != 5) return;
cc_string addr, user, mppass;
if (!DirectUrl_Claims(str, &addr, &user, &mppass)) return;
LInput_SetString(&DirectConnectScreen.iptAddress, &parts[2]);
LInput_SetString(&DirectConnectScreen.iptUsername, &parts[3]);
LInput_SetString(&DirectConnectScreen.iptMppass, &parts[4]);
LInput_SetString(&DirectConnectScreen.iptAddress, &addr);
LInput_SetString(&DirectConnectScreen.iptUsername, &user);
LInput_SetString(&DirectConnectScreen.iptMppass, &mppass);
str->length = 0;
}
static void DirectConnectScreen_StartClient(void* w) {
static const cc_string defMppass = String_FromConst("(none)");
static const cc_string defPort = String_FromConst("25565");
const cc_string* user = &DirectConnectScreen.iptUsername.text;
const cc_string* addr = &DirectConnectScreen.iptAddress.text;
const cc_string* mppass = &DirectConnectScreen.iptMppass.text;
struct LLabel* status = &DirectConnectScreen.lblStatus;
cc_string ip, port;
cc_uint16 raw_port;
cc_sockaddr addrs[SOCKET_MAX_ADDRS];
int numAddrs;
int numAddrs, raw_port;
int index = String_LastIndexOf(addr, ':');
if (index == 0 || index == addr->length - 1) {
LLabel_SetConst(status, "&cInvalid address"); return;
}
/* support either "[IP]" or "[IP]:[PORT]" */
if (index == -1) {
ip = *addr;
port = defPort;
} else {
ip = String_UNSAFE_Substring(addr, 0, index);
port = String_UNSAFE_SubstringAt(addr, index + 1);
}
if (!user->length) {
LLabel_SetConst(status, "&cUsername required"); return;
}
if (!DirectUrl_ExtractAddress(addr, &ip, &port, &raw_port)) {
LLabel_SetConst(status, "&cInvalid port"); return;
}
if (Socket_ParseAddress(&ip, 0, addrs, &numAddrs)) {
LLabel_SetConst(status, "&cInvalid ip"); return;
}
if (!Convert_ParseUInt16(&port, &raw_port)) {
LLabel_SetConst(status, "&cInvalid port"); return;
}
if (!mppass->length) mppass = &defMppass;
Options_PauseSaving();

View File

@ -365,3 +365,36 @@ int EntryList_Find(struct StringsBuffer* list, const cc_string* key, char separa
}
return -1;
}
/*########################################################################################################################*
*--------------------------------------------------------Direct URL-------------------------------------------------------*
*#########################################################################################################################*/
cc_bool DirectUrl_Claims(const cc_string* input, cc_string* addr, cc_string* user, cc_string* mppass) {
static const cc_string prefix = String_FromConst("mc://");
cc_string parts[6];
if (!String_CaselessStarts(input, &prefix)) return false;
/* mc://[ip:port]/[username]/[mppass] */
if (String_UNSAFE_Split(input, '/', parts, 6) != 5) return false;
*addr = parts[2];
*user = parts[3];
*mppass = parts[4];
return true;
}
cc_bool DirectUrl_ExtractAddress(const cc_string* addr, cc_string* ip, cc_string* port, int* portNum) {
static const cc_string defPort = String_FromConst("25565");
int index = String_LastIndexOf(addr, ':');
/* support either "[IP]" or "[IP]:[PORT]" */
if (index == -1) {
*ip = *addr;
*port = defPort;
} else {
*ip = String_UNSAFE_Substring(addr, 0, index);
*port = String_UNSAFE_SubstringAt(addr, index + 1);
}
return Convert_ParseInt(port, portNum) && *portNum >= 0 && *portNum <= 65535;
}

View File

@ -74,4 +74,7 @@ CC_NOINLINE void EntryList_Set(struct StringsBuffer* list, const cc_string* key,
CC_NOINLINE STRING_REF cc_string EntryList_UNSAFE_Get(struct StringsBuffer* list, const cc_string* key, char separator);
/* Finds the index of the entry whose key caselessly equals the given key. */
CC_NOINLINE int EntryList_Find(struct StringsBuffer* list, const cc_string* key, char separator);
cc_bool DirectUrl_Claims(const cc_string* STRING_REF input, cc_string* addr, cc_string* user, cc_string* mppass);
cc_bool DirectUrl_ExtractAddress(const cc_string* STRING_REF addr, cc_string* ip, cc_string* port, int* portNum);
#endif

View File

@ -389,7 +389,7 @@ void Gamepads_Init(void) {
}
void Gamepads_Process(float delta) {
void Gamepads_Process(float delta) { }
static void Cursor_GetRawPos(int* x, int* y) {
Point point;

View File

@ -491,7 +491,7 @@ void Gamepads_Init(void) {
}
void Gamepads_Process(float delta) {
void Gamepads_Process(float delta) { }
static int mouseX, mouseY;
static void SetMousePosition(int x, int y) {

View File

@ -170,7 +170,7 @@ void Gamepads_Init(void) {
Input.Sources |= INPUT_SOURCE_GAMEPAD;
KPADInit();
VPADInit()
VPADInit();
}
static void ProcessKPadButtons(int port, int mods) {

View File

@ -100,6 +100,15 @@ static int RunProgram(int argc, char** argv) {
String_Copy(&SP_AutoloadMap, &args[0]); /* TODO: don't copy args? */
RunGame();
#endif
} else if (argsCount == 1 && DirectUrl_Claims(&args[0], &args[1], &args[2], &args[3])) {
String_Copy(&Game_Username, &args[2]);
String_Copy(&Game_Mppass, &args[3]);
if (!DirectUrl_ExtractAddress(&args[1], &Server.Address, &args[4], &Server.Port)) {
WarnInvalidArg("Invalid port", &args[4]);
return 1;
}
RunGame();
} else if (argsCount == 1) {
String_Copy(&Game_Username, &args[0]);
RunGame();
@ -111,11 +120,10 @@ static int RunProgram(int argc, char** argv) {
String_Copy(&Game_Mppass, &args[1]);
String_Copy(&Server.Address,&args[2]);
if (!Convert_ParseUInt16(&args[3], &port)) {
if (!Convert_ParseInt(&args[3], &Server.Port) || port < 0 || port > 65535) {
WarnInvalidArg("Invalid port", &args[3]);
return 1;
}
Server.Port = port;
RunGame();
}
return 0;