From 4cb9e200ed3856e47d984eff6fbb01bd59fae0ce Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Wed, 26 Jun 2024 23:30:04 +1000 Subject: [PATCH] Support mc:// urls as command line argument --- ios/CCIOS.xcodeproj/project.pbxproj | 8 +++--- misc/macOS/CCMAC.xcodeproj/project.pbxproj | 8 +++--- src/LScreens.c | 32 ++++++--------------- src/Utils.c | 33 ++++++++++++++++++++++ src/Utils.h | 3 ++ src/Window_MacClassic.c | 2 +- src/Window_Terminal.c | 2 +- src/Window_WiiU.cpp | 2 +- src/main.c | 12 ++++++-- 9 files changed, 66 insertions(+), 36 deletions(-) diff --git a/ios/CCIOS.xcodeproj/project.pbxproj b/ios/CCIOS.xcodeproj/project.pbxproj index 17ce23b15..3538aa67b 100644 --- a/ios/CCIOS.xcodeproj/project.pbxproj +++ b/ios/CCIOS.xcodeproj/project.pbxproj @@ -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 = ""; }; 9A89D4DD27F802F600FF3F80 /* Launcher.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = Launcher.c; sourceTree = ""; }; 9A89D4E327F802F600FF3F80 /* Options.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = Options.c; sourceTree = ""; }; - 9A89D4E427F802F600FF3F80 /* Window_SDL.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = Window_SDL.c; sourceTree = ""; }; + 9A89D4E427F802F600FF3F80 /* Window_SDL2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = Window_SDL2.c; sourceTree = ""; }; 9A89D4E727F802F600FF3F80 /* Audio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = Audio.c; sourceTree = ""; }; 9A89D4E827F802F600FF3F80 /* Stream.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = Stream.c; sourceTree = ""; }; 9A89D4E927F802F600FF3F80 /* Vectors.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = Vectors.c; sourceTree = ""; }; @@ -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 */, diff --git a/misc/macOS/CCMAC.xcodeproj/project.pbxproj b/misc/macOS/CCMAC.xcodeproj/project.pbxproj index ba25f3284..2a8bdd2b3 100644 --- a/misc/macOS/CCMAC.xcodeproj/project.pbxproj +++ b/misc/macOS/CCMAC.xcodeproj/project.pbxproj @@ -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 = ""; }; 9A6C7BFE2C073DEE00676D27 /* SSL.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SSL.c; path = "../../../../../../ClassiCube-master/src/SSL.c"; sourceTree = ""; }; 9A6C7BFF2C073DEE00676D27 /* LBackend_Android.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = LBackend_Android.c; path = "../../../../../../ClassiCube-master/src/LBackend_Android.c"; sourceTree = ""; }; - 9A6C7C002C073DEE00676D27 /* Window_SDL.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Window_SDL.c; path = "../../../../../../ClassiCube-master/src/Window_SDL.c"; sourceTree = ""; }; + 9A6C7C002C073DEE00676D27 /* Window_SDL2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Window_SDL2.c; path = "../../../../../../ClassiCube-master/src/Window_SDL2.c"; sourceTree = ""; }; 9A6C7C012C073DEE00676D27 /* Graphics_GL2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Graphics_GL2.c; path = "../../../../../../ClassiCube-master/src/Graphics_GL2.c"; sourceTree = ""; }; 9A6C7C022C073DEE00676D27 /* Lighting.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Lighting.c; path = "../../../../../../ClassiCube-master/src/Lighting.c"; sourceTree = ""; }; 9A6C7C032C073DEF00676D27 /* Http.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Http.h; path = "../../../../../../ClassiCube-master/src/Http.h"; sourceTree = ""; }; @@ -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 */, diff --git a/src/LScreens.c b/src/LScreens.c index 395be7658..a798b12d2 100644 --- a/src/LScreens.c +++ b/src/LScreens.c @@ -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(); diff --git a/src/Utils.c b/src/Utils.c index 8fffdaeea..f6e27637d 100644 --- a/src/Utils.c +++ b/src/Utils.c @@ -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; +} diff --git a/src/Utils.h b/src/Utils.h index 78995c0ef..09fc54adb 100644 --- a/src/Utils.h +++ b/src/Utils.h @@ -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 diff --git a/src/Window_MacClassic.c b/src/Window_MacClassic.c index a86832bbc..8fdea6020 100644 --- a/src/Window_MacClassic.c +++ b/src/Window_MacClassic.c @@ -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; diff --git a/src/Window_Terminal.c b/src/Window_Terminal.c index 7c2cce719..423d95066 100644 --- a/src/Window_Terminal.c +++ b/src/Window_Terminal.c @@ -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) { diff --git a/src/Window_WiiU.cpp b/src/Window_WiiU.cpp index 0fa4d8797..f81009d08 100644 --- a/src/Window_WiiU.cpp +++ b/src/Window_WiiU.cpp @@ -170,7 +170,7 @@ void Gamepads_Init(void) { Input.Sources |= INPUT_SOURCE_GAMEPAD; KPADInit(); - VPADInit() + VPADInit(); } static void ProcessKPadButtons(int port, int mods) { diff --git a/src/main.c b/src/main.c index 034004504..761e82ed4 100644 --- a/src/main.c +++ b/src/main.c @@ -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;