mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-16 03:23:15 +01:00
Add openrct2:// uri scheme support
This sets up a URI scheme for openrct2 for Windows by adding the necessary registry keys. This is done on startup every time to keep the binary location up to date. URI handling currently supports joining a server.
This commit is contained in:
@@ -110,4 +110,5 @@ namespace CommandLine
|
||||
exitcode_t HandleCommandDefault();
|
||||
|
||||
exitcode_t HandleCommandConvert(CommandLineArgEnumerator * enumerator);
|
||||
exitcode_t HandleCommandUri(CommandLineArgEnumerator * enumerator);
|
||||
}
|
||||
|
||||
@@ -126,6 +126,7 @@ const CommandLineCommand CommandLine::RootCommands[]
|
||||
DefineCommand("set-rct2", "<path>", StandardOptions, HandleCommandSetRCT2),
|
||||
DefineCommand("convert", "<source> <destination>", StandardOptions, CommandLine::HandleCommandConvert),
|
||||
DefineCommand("scan-objects", "<path>", StandardOptions, HandleCommandScanObjects),
|
||||
DefineCommand("handle-uri", "openrct2://.../", StandardOptions, CommandLine::HandleCommandUri),
|
||||
|
||||
#if defined(__WINDOWS__) && !defined(__MINGW32__)
|
||||
DefineCommand("register-shell", "", RegisterShellOptions, HandleCommandRegisterShell),
|
||||
|
||||
93
src/openrct2/cmdline/UriHandler.cpp
Normal file
93
src/openrct2/cmdline/UriHandler.cpp
Normal file
@@ -0,0 +1,93 @@
|
||||
#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
|
||||
/*****************************************************************************
|
||||
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
|
||||
*
|
||||
* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
|
||||
* For more information, visit https://github.com/OpenRCT2/OpenRCT2
|
||||
*
|
||||
* OpenRCT2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* A full copy of the GNU General Public License can be found in licence.txt
|
||||
*****************************************************************************/
|
||||
#pragma endregion
|
||||
|
||||
#include "../core/Console.hpp"
|
||||
#include "../core/Memory.hpp"
|
||||
#include "../core/String.hpp"
|
||||
#include "../network/network.h"
|
||||
#include "CommandLine.hpp"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "../openrct2.h"
|
||||
}
|
||||
|
||||
static exitcode_t HandleUri(const utf8 * uri);
|
||||
|
||||
exitcode_t CommandLine::HandleCommandUri(CommandLineArgEnumerator * enumerator)
|
||||
{
|
||||
const utf8 * uri;
|
||||
if (enumerator->TryPopString(&uri))
|
||||
{
|
||||
if (String::StartsWith(uri, "openrct2://"))
|
||||
{
|
||||
const utf8 * uriCommand = uri + 11;
|
||||
return HandleUri(uriCommand);
|
||||
}
|
||||
}
|
||||
|
||||
Console::Error::WriteLine("Invalid URI");
|
||||
return EXITCODE_FAIL;
|
||||
}
|
||||
|
||||
static exitcode_t HandleUri(const utf8 * uri)
|
||||
{
|
||||
utf8 * * args;
|
||||
size_t numArgs = String::Split(&args, uri, '/');
|
||||
if (numArgs > 0)
|
||||
{
|
||||
utf8 * arg = args[0];
|
||||
if (String::Equals(arg, "join"))
|
||||
{
|
||||
if (numArgs > 1)
|
||||
{
|
||||
utf8 * hostnamePort = args[1];
|
||||
|
||||
// Argument is in hostname:port format, so we need to split
|
||||
utf8 * hostname = String::Duplicate(hostnamePort);
|
||||
sint32 port = NETWORK_DEFAULT_PORT;
|
||||
size_t colonIndex = String::IndexOf(hostnamePort, ':');
|
||||
if (colonIndex != SIZE_MAX)
|
||||
{
|
||||
Memory::Free(hostname);
|
||||
hostname = String::Substring(hostnamePort, 0, colonIndex);
|
||||
port = atoi(hostnamePort + colonIndex + 1);
|
||||
}
|
||||
|
||||
// Set the network start configuration
|
||||
gNetworkStart = NETWORK_MODE_CLIENT;
|
||||
String::Set(gNetworkStartHost, sizeof(gNetworkStartHost), hostname);
|
||||
gNetworkStartPort = port;
|
||||
|
||||
Memory::Free(hostname);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console::Error::WriteLine("Expected hostname:port after join");
|
||||
return EXITCODE_FAIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clean up
|
||||
for (size_t i = 0; i < numArgs; i++)
|
||||
{
|
||||
Memory::Free(args[i]);
|
||||
}
|
||||
Memory::FreeArray(args, numArgs);
|
||||
|
||||
return EXITCODE_CONTINUE;
|
||||
}
|
||||
@@ -72,6 +72,7 @@
|
||||
<ClCompile Include="audio\FileAudioSource.cpp" />
|
||||
<ClCompile Include="audio\MemoryAudioSource.cpp" />
|
||||
<ClCompile Include="audio\NullAudioSource.cpp" />
|
||||
<ClCompile Include="cmdline\UriHandler.cpp" />
|
||||
<ClCompile Include="config\Config.cpp" />
|
||||
<ClCompile Include="config\IniReader.cpp" />
|
||||
<ClCompile Include="config\IniWriter.cpp" />
|
||||
|
||||
@@ -224,6 +224,7 @@ void core_init();
|
||||
HWND windows_get_window_handle();
|
||||
void platform_setup_file_associations();
|
||||
void platform_remove_file_associations();
|
||||
bool platform_setup_uri_protocol();
|
||||
// This function cannot be marked as 'static', even though it may seem to be,
|
||||
// as it requires external linkage, which 'static' prevents
|
||||
__declspec(dllexport) sint32 StartOpenRCT(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, sint32 nCmdShow);
|
||||
|
||||
@@ -1040,7 +1040,8 @@ utf8* platform_get_username() {
|
||||
// File association setup
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define SOFTWARE_CLASSES L"Software\\Classes"
|
||||
#define SOFTWARE_CLASSES L"Software\\Classes"
|
||||
#define MUI_CACHE L"Local Settings\\Software\\Microsoft\\Windows\\Shell\\MuiCache"
|
||||
|
||||
static void get_progIdName(wchar_t *dst, const utf8 *extension)
|
||||
{
|
||||
@@ -1183,4 +1184,50 @@ void platform_remove_file_associations()
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// URI protocol association setup
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool platform_setup_uri_protocol()
|
||||
{
|
||||
log_verbose("Setting up URI protocol...");
|
||||
|
||||
// [HKEY_CURRENT_USER\Software\Classes]
|
||||
HKEY hRootKey;
|
||||
if (RegOpenKeyW(HKEY_CURRENT_USER, SOFTWARE_CLASSES, &hRootKey) == ERROR_SUCCESS) {
|
||||
// [hRootKey\openrct2]
|
||||
HKEY hClassKey;
|
||||
if (RegCreateKeyA(hRootKey, "openrct2", &hClassKey) == ERROR_SUCCESS) {
|
||||
if (RegSetValueA(hClassKey, NULL, REG_SZ, "URL:openrct2", 0) == ERROR_SUCCESS) {
|
||||
if (RegSetKeyValueA(hClassKey, NULL, "URL Protocol", REG_SZ, "", 0) == ERROR_SUCCESS) {
|
||||
// [hRootKey\openrct2\shell\open\command]
|
||||
wchar_t exePath[MAX_PATH];
|
||||
GetModuleFileNameW(NULL, exePath, MAX_PATH);
|
||||
|
||||
wchar_t buffer[512];
|
||||
swprintf_s(buffer, sizeof(buffer), L"\"%s\" handle-uri \"%%1\"", exePath);
|
||||
if (RegSetValueW(hClassKey, L"shell\\open\\command", REG_SZ, buffer, 0) == ERROR_SUCCESS) {
|
||||
// Not compulsory, but gives the application a nicer name
|
||||
// [HKEY_CURRENT_USER\SOFTWARE\Classes\Local Settings\Software\Microsoft\Windows\Shell\MuiCache]
|
||||
HKEY hMuiCacheKey;
|
||||
if (RegCreateKeyW(hRootKey, MUI_CACHE, &hMuiCacheKey) == ERROR_SUCCESS) {
|
||||
swprintf_s(buffer, sizeof(buffer), L"%s.FriendlyAppName", exePath);
|
||||
RegSetKeyValueW(hMuiCacheKey, NULL, buffer, REG_SZ, L"OpenRCT2", sizeof(L"OpenRCT2") + 1);
|
||||
}
|
||||
|
||||
log_verbose("URI protocol setup successful");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log_verbose("URI protocol setup failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user