Merge branch 'master' of github.com:traintastic/traintastic
Dieser Commit ist enthalten in:
Commit
feab3a6c52
@ -157,7 +157,7 @@ bool Session::processMessage(const Message& message)
|
||||
{
|
||||
if(ObjectPtr object = m_handles.getItem(message.read<Handle>()))
|
||||
{
|
||||
if(AbstractProperty* property = object->getProperty(message.read<std::string>()))
|
||||
if(AbstractProperty* property = object->getProperty(message.read<std::string>()); property && !property->isInternal())
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -206,7 +206,7 @@ bool Session::processMessage(const Message& message)
|
||||
{
|
||||
if(ObjectPtr object = m_handles.getItem(message.read<Handle>()))
|
||||
{
|
||||
if(AbstractUnitProperty* property = dynamic_cast<AbstractUnitProperty*>(object->getProperty(message.read<std::string>())))
|
||||
if(AbstractUnitProperty* property = dynamic_cast<AbstractUnitProperty*>(object->getProperty(message.read<std::string>())); property && !property->isInternal())
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -225,7 +225,7 @@ bool Session::processMessage(const Message& message)
|
||||
{
|
||||
if(ObjectPtr object = m_handles.getItem(message.read<Handle>()))
|
||||
{
|
||||
if(AbstractObjectProperty* property = dynamic_cast<AbstractObjectProperty*>(object->getProperty(message.read<std::string>())))
|
||||
if(AbstractObjectProperty* property = dynamic_cast<AbstractObjectProperty*>(object->getProperty(message.read<std::string>())); property && !property->isInternal())
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -253,7 +253,7 @@ bool Session::processMessage(const Message& message)
|
||||
{
|
||||
if(ObjectPtr object = m_handles.getItem(message.read<Handle>()))
|
||||
{
|
||||
if(AbstractMethod* method = object->getMethod(message.read<std::string>()))
|
||||
if(AbstractMethod* method = object->getMethod(message.read<std::string>()); method && !method->isInternal())
|
||||
{
|
||||
const ValueType resultType = message.read<ValueType>();
|
||||
const uint8_t argumentCount = message.read<uint8_t>();
|
||||
|
||||
97
server/src/os/windows/registry.cpp
Normale Datei
97
server/src/os/windows/registry.cpp
Normale Datei
@ -0,0 +1,97 @@
|
||||
/**
|
||||
* server/src/os/windows/registry.cpp
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2022 Reinder Feenstra
|
||||
*
|
||||
* This program 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 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "registry.hpp"
|
||||
#include <string>
|
||||
#include <windows.h>
|
||||
|
||||
namespace Windows::Registry {
|
||||
|
||||
const char* runKey = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run";
|
||||
//const char* runTraintasticServerKey = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\\TraintasticServer";
|
||||
const char* startupApprovedKey = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StartupApproved\\Run";
|
||||
const char* traintasticServerKey = "TraintasticServer";
|
||||
const WCHAR* traintasticServerKeyW = L"TraintasticServer";
|
||||
const DWORD startupEnabled = 2;
|
||||
const DWORD startupDisabled = 3;
|
||||
|
||||
bool addRun()
|
||||
{
|
||||
bool success = false;
|
||||
HKEY key;
|
||||
LSTATUS r = RegOpenKeyExA(HKEY_CURRENT_USER, runKey, 0, KEY_WRITE, &key);
|
||||
if(r == ERROR_SUCCESS)
|
||||
{
|
||||
std::basic_string<WCHAR> path;
|
||||
path.resize(MAX_PATH);
|
||||
path[0] = '"';
|
||||
const DWORD l = GetModuleFileNameW(nullptr, path.data() + 1, path.size() - 1);
|
||||
if(l > 0)
|
||||
{
|
||||
path.resize(1 + l);
|
||||
path.append(L"\" --tray");
|
||||
|
||||
r = RegSetValueExW(key, traintasticServerKeyW, 0, REG_SZ, reinterpret_cast<const BYTE*>(path.c_str()), (path.size() + 1) * sizeof(WCHAR));
|
||||
success = (r == ERROR_SUCCESS);
|
||||
}
|
||||
RegCloseKey(key);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
bool getStartUpApproved(bool& enabled)
|
||||
{
|
||||
bool success = false;
|
||||
HKEY key;
|
||||
LSTATUS r = RegOpenKeyExA(HKEY_CURRENT_USER, startupApprovedKey, 0, KEY_READ, &key);
|
||||
if(r == ERROR_SUCCESS)
|
||||
{
|
||||
DWORD data[3];
|
||||
DWORD size = sizeof(data);
|
||||
r = RegGetValueA(key, nullptr, traintasticServerKey, RRF_RT_REG_BINARY, nullptr, &data, &size);
|
||||
if(r == ERROR_SUCCESS)
|
||||
{
|
||||
enabled = (data[0] == startupEnabled);
|
||||
success = true;
|
||||
}
|
||||
RegCloseKey(key);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
bool setStartUpApproved(bool enabled)
|
||||
{
|
||||
bool success = false;
|
||||
HKEY key;
|
||||
LSTATUS r = RegOpenKeyExA(HKEY_CURRENT_USER, startupApprovedKey, 0, KEY_WRITE, &key);
|
||||
if(r == ERROR_SUCCESS)
|
||||
{
|
||||
DWORD data[3] = {enabled ? startupEnabled : startupDisabled, 0, 0};
|
||||
DWORD size = sizeof(data);
|
||||
r = RegSetValueExA(key, traintasticServerKey, 0, REG_BINARY, reinterpret_cast<const BYTE*>(&data), size);
|
||||
success = (r == ERROR_SUCCESS);
|
||||
RegCloseKey(key);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
}
|
||||
35
server/src/os/windows/registry.hpp
Normale Datei
35
server/src/os/windows/registry.hpp
Normale Datei
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* server/src/os/windows/registry.hpp
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2022 Reinder Feenstra
|
||||
*
|
||||
* This program 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 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef TRAINTASTIC_SERVER_OS_WINDOWS_REGISTRY_HPP
|
||||
#define TRAINTASTIC_SERVER_OS_WINDOWS_REGISTRY_HPP
|
||||
|
||||
namespace Windows::Registry {
|
||||
|
||||
bool addRun();
|
||||
|
||||
bool getStartUpApproved(bool& enabled);
|
||||
bool setStartUpApproved(bool enabled);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -25,8 +25,10 @@
|
||||
#include <version.hpp>
|
||||
#include <traintastic/codename.hpp>
|
||||
#include "consolewindow.hpp"
|
||||
#include "registry.hpp"
|
||||
#include "../../core/eventloop.hpp"
|
||||
#include "../../traintastic/traintastic.hpp"
|
||||
#include "../../utils/setthreadname.hpp"
|
||||
|
||||
namespace Windows {
|
||||
|
||||
@ -50,6 +52,8 @@ void TrayIcon::remove()
|
||||
|
||||
void TrayIcon::run()
|
||||
{
|
||||
setThreadName("trayicon");
|
||||
|
||||
const LPCSTR windowClassName = "TraintasticServerTrayIcon";
|
||||
|
||||
// register window class:
|
||||
@ -73,9 +77,18 @@ void TrayIcon::run()
|
||||
s_menu = CreatePopupMenu();
|
||||
menuAddItem(MenuItem::ShowHideConsole, "Show/hide console", hasConsoleWindow());
|
||||
menuAddSeperator();
|
||||
menuAddItem(MenuItem::AllowClientServerRestart, "Allow client to restart server");
|
||||
menuAddItem(MenuItem::AllowClientServerShutdown, "Allow client to shutdown server");
|
||||
menuAddSeperator();
|
||||
menuAddItem(MenuItem::StartAutomaticallyAtLogon, "Start automatically at logon");
|
||||
menuAddSeperator();
|
||||
menuAddItem(MenuItem::Restart, "Restart");
|
||||
menuAddItem(MenuItem::Shutdown, "Shutdown");
|
||||
|
||||
bool startUpApproved = false;
|
||||
Registry::getStartUpApproved(startUpApproved);
|
||||
menuSetItemChecked(MenuItem::StartAutomaticallyAtLogon, startUpApproved);
|
||||
|
||||
// setup tray icon:
|
||||
static NOTIFYICONDATA notifyIconData;
|
||||
memset(¬ifyIconData, 0, sizeof(notifyIconData));
|
||||
@ -97,6 +110,9 @@ void TrayIcon::run()
|
||||
|
||||
Shell_NotifyIcon(NIM_ADD, ¬ifyIconData);
|
||||
|
||||
// Get settings:
|
||||
EventLoop::call(getSettings);
|
||||
|
||||
// message loop:
|
||||
while(true)
|
||||
{
|
||||
@ -166,8 +182,57 @@ LRESULT CALLBACK TrayIcon::windowProc(_In_ HWND hWnd, _In_ UINT uMsg, _In_ WPARA
|
||||
case MenuItem::ShowHideConsole:
|
||||
setConsoleWindowVisible(!isConsoleWindowVisible());
|
||||
return 0;
|
||||
|
||||
case MenuItem::AllowClientServerRestart:
|
||||
{
|
||||
bool value;
|
||||
{
|
||||
std::lock_guard lock{s_settings.mutex};
|
||||
value = !s_settings.allowClientServerRestart;
|
||||
}
|
||||
EventLoop::call(
|
||||
[value]()
|
||||
{
|
||||
Traintastic::instance->settings->allowClientServerRestart = value;
|
||||
getSettings();
|
||||
});
|
||||
break;
|
||||
}
|
||||
case MenuItem::AllowClientServerShutdown:
|
||||
{
|
||||
bool value;
|
||||
{
|
||||
std::lock_guard lock{s_settings.mutex};
|
||||
value = !s_settings.allowClientServerShutdown;
|
||||
}
|
||||
EventLoop::call(
|
||||
[value]()
|
||||
{
|
||||
Traintastic::instance->settings->allowClientServerShutdown = value;
|
||||
getSettings();
|
||||
});
|
||||
break;
|
||||
}
|
||||
case MenuItem::StartAutomaticallyAtLogon:
|
||||
{
|
||||
bool startUpApproved = !menuGetItemChecked(MenuItem::StartAutomaticallyAtLogon);
|
||||
if(startUpApproved)
|
||||
Registry::addRun();
|
||||
Registry::setStartUpApproved(startUpApproved);
|
||||
if(Registry::getStartUpApproved(startUpApproved))
|
||||
menuSetItemChecked(MenuItem::StartAutomaticallyAtLogon, startUpApproved);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_TRAINTASTIC_SETTINGS:
|
||||
{
|
||||
std::lock_guard lock{s_settings.mutex};
|
||||
menuSetItemChecked(MenuItem::AllowClientServerRestart, s_settings.allowClientServerRestart);
|
||||
menuSetItemChecked(MenuItem::AllowClientServerShutdown, s_settings.allowClientServerShutdown);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
@ -197,4 +262,28 @@ void TrayIcon::menuAddSeperator()
|
||||
InsertMenuItem(s_menu, GetMenuItemCount(s_menu), TRUE, &item);
|
||||
}
|
||||
|
||||
bool TrayIcon::menuGetItemChecked(MenuItem id)
|
||||
{
|
||||
assert(s_menu);
|
||||
return GetMenuState(s_menu, static_cast<UINT>(id), MF_BYCOMMAND) & MF_CHECKED;
|
||||
}
|
||||
|
||||
void TrayIcon::menuSetItemChecked(MenuItem id, bool checked)
|
||||
{
|
||||
assert(s_menu);
|
||||
CheckMenuItem(s_menu, static_cast<UINT>(id), checked ? MF_CHECKED : MF_UNCHECKED);
|
||||
}
|
||||
|
||||
void TrayIcon::getSettings()
|
||||
{
|
||||
assert(isEventLoopThread());
|
||||
const auto& settings = *Traintastic::instance->settings.value();
|
||||
{
|
||||
std::lock_guard lock{s_settings.mutex};
|
||||
s_settings.allowClientServerRestart = settings.allowClientServerRestart;
|
||||
s_settings.allowClientServerShutdown = settings.allowClientServerShutdown;
|
||||
}
|
||||
PostMessage(s_window, WM_TRAINTASTIC_SETTINGS, 0, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#define _WINSOCKAPI_ // prevent windows.h including winsock.h
|
||||
#include <windows.h>
|
||||
@ -43,19 +44,35 @@ class TrayIcon
|
||||
Shutdown = 1,
|
||||
Restart = 2,
|
||||
ShowHideConsole = 3,
|
||||
AllowClientServerRestart = 4,
|
||||
AllowClientServerShutdown = 5,
|
||||
StartAutomaticallyAtLogon = 6,
|
||||
};
|
||||
|
||||
struct TraintasticSettings
|
||||
{
|
||||
std::mutex mutex;
|
||||
bool allowClientServerRestart;
|
||||
bool allowClientServerShutdown;
|
||||
};
|
||||
|
||||
static constexpr UINT WM_NOTIFYICON_CALLBACK = WM_USER + 1;
|
||||
static constexpr UINT WM_TRAINTASTIC_SETTINGS = WM_USER + 2;
|
||||
|
||||
static std::unique_ptr<std::thread> s_thread;
|
||||
static HWND s_window;
|
||||
static HMENU s_menu;
|
||||
inline static TraintasticSettings s_settings = {{}, false, false};
|
||||
|
||||
static void run();
|
||||
static LRESULT CALLBACK windowProc(_In_ HWND hWnd, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam);
|
||||
|
||||
static void menuAddItem(MenuItem id, const LPSTR text, bool enabled = true);
|
||||
static void menuAddSeperator();
|
||||
static bool menuGetItemChecked(MenuItem id);
|
||||
static void menuSetItemChecked(MenuItem id, bool checked);
|
||||
|
||||
static void getSettings();
|
||||
|
||||
public:
|
||||
static void add();
|
||||
|
||||
@ -54,8 +54,8 @@ Settings::Settings(const std::filesystem::path& path)
|
||||
, loadLastWorldOnStartup{this, "load_last_world_on_startup", true, PropertyFlags::ReadWrite, [this](const bool& /*value*/){ saveToFile(); }}
|
||||
, autoSaveWorldOnExit{this, "auto_save_world_on_exit", false, PropertyFlags::ReadWrite, [this](const bool& /*value*/){ saveToFile(); }}
|
||||
, saveWorldUncompressed{this, "save_world_uncompressed", false, PropertyFlags::ReadWrite, [this](const bool& /*value*/){ saveToFile(); }}
|
||||
, allowClientServerRestart{this, "allow_client_server_restart", false, PropertyFlags::ReadWrite, [this](const bool& /*value*/){ saveToFile(); }}
|
||||
, allowClientServerShutdown{this, "allow_client_server_shutdown", false, PropertyFlags::ReadWrite, [this](const bool& /*value*/){ saveToFile(); }}
|
||||
, allowClientServerRestart{this, "allow_client_server_restart", false, PropertyFlags::ReadWrite | PropertyFlags::Internal, [this](const bool& /*value*/){ saveToFile(); }}
|
||||
, allowClientServerShutdown{this, "allow_client_server_shutdown", false, PropertyFlags::ReadWrite | PropertyFlags::Internal, [this](const bool& /*value*/){ saveToFile(); }}
|
||||
, memoryLoggerSize{this, Name::memoryLoggerSize, Default::memoryLoggerSize, PropertyFlags::ReadWrite, [this](const uint32_t& /*value*/){ saveToFile(); }}
|
||||
, enableFileLogger{this, Name::enableFileLogger, Default::enableFileLogger, PropertyFlags::ReadWrite, [this](const bool& /*value*/){ saveToFile(); }}
|
||||
{
|
||||
|
||||
Laden…
x
In neuem Issue referenzieren
Einen Benutzer sperren