Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
cs_server.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6/* ScriptData
7Name: server_commandscript
8%Complete: 100
9Comment: All server related commands
10Category: commandscripts
11EndScriptData */
12
13#include "Chat.h"
14#include "Config.h"
15#include "Language.h"
16#include "MemoryUsage.h"
17#include "MapManager.h"
18#include "ObjectAccessor.h"
19#include "Player.h"
20#include "RuntimeMetrics.h"
21#include "ScriptMgr.h"
23#include "SystemConfig.h"
24
26{
27public:
28 server_commandscript() : CommandScript("server_commandscript") { }
29
30 std::vector<ChatCommand> GetCommands() const OVERRIDE
31 {
32 static std::vector<ChatCommand> serverIdleRestartCommandTable =
33 {
36 };
37
38 static std::vector<ChatCommand> serverIdleShutdownCommandTable =
39 {
42 };
43
44 static std::vector<ChatCommand> serverRestartCommandTable =
45 {
49 };
50
51 static std::vector<ChatCommand> serverShutdownCommandTable =
52 {
55 };
56
57 static std::vector<ChatCommand> serverMetricsCommandTable =
58 {
61 };
62
63 static std::vector<ChatCommand> serverSetCommandTable =
64 {
69 };
70
71 static std::vector<ChatCommand> serverCommandTable =
72 {
75 { "idlerestart", rbac::RBAC_PERM_COMMAND_SERVER_IDLERESTART, true, NULL, "", serverIdleRestartCommandTable },
76 { "idleshutdown", rbac::RBAC_PERM_COMMAND_SERVER_IDLESHUTDOWN, true, NULL, "", serverIdleShutdownCommandTable },
78 { "metrics", rbac::RBAC_PERM_COMMAND_SERVER_INFO, true, NULL, "", serverMetricsCommandTable },
81 { "restart", rbac::RBAC_PERM_COMMAND_SERVER_RESTART, true, NULL, "", serverRestartCommandTable },
82 { "shutdown", rbac::RBAC_PERM_COMMAND_SERVER_SHUTDOWN, true, NULL, "", serverShutdownCommandTable },
83 { "set", rbac::RBAC_PERM_COMMAND_SERVER_SET, true, NULL, "", serverSetCommandTable },
85 };
86
87 static std::vector<ChatCommand> commandTable =
88 {
89 { "server", rbac::RBAC_PERM_COMMAND_SERVER, true, NULL, "", serverCommandTable },
90 };
91 return commandTable;
92 }
93
94 // Triggering corpses expire check in world
95 static bool HandleServerCorpsesCommand(ChatHandler* /*handler*/, char const* /*args*/)
96 {
97 sObjectAccessor->RemoveOldCorpses();
98 return true;
99 }
100
101 static void SendRuntimeMetrics(ChatHandler* handler)
102 {
103 std::vector<std::string> runtimeMetrics =
105 for (std::vector<std::string>::const_iterator itr = runtimeMetrics.begin(); itr != runtimeMetrics.end(); ++itr)
106 handler->PSendSysMessage("%s", itr->c_str());
107
108 DelayExecutorMetricsSnapshot delayExecutorMetrics = sMapMgr->GetMapUpdater()->GetExecutorMetricsSnapshot();
109 handler->PSendSysMessage("Runtime metrics - Delay executor: submitted " UI64FMTD ", completed " UI64FMTD
110 ", rejected " UI64FMTD ", backlog %u, high-water %u, high-water events " UI64FMTD,
111 delayExecutorMetrics.Submitted, delayExecutorMetrics.Completed, delayExecutorMetrics.Rejected,
112 delayExecutorMetrics.Backlog, delayExecutorMetrics.BacklogHighWater,
113 delayExecutorMetrics.BacklogHighWaterEvents);
114 }
115
116 static bool HandleServerMetricsCommand(ChatHandler* handler, char const* /*args*/)
117 {
118 SendRuntimeMetrics(handler);
119 return true;
120 }
121
122 static bool HandleServerMetricsResetCommand(ChatHandler* handler, char const* /*args*/)
123 {
125 sMapMgr->GetMapUpdater()->ResetExecutorMetrics();
126 handler->SendSysMessage("Runtime metrics reset.");
127 return true;
128 }
129
130 static bool HandleServerInfoCommand(ChatHandler* handler, char const* /*args*/)
131 {
132 uint32 playersNum = sWorld->GetPlayerCount();
133 uint32 maxPlayersNum = sWorld->GetMaxPlayerCount();
134 uint32 activeClientsNum = sWorld->GetActiveSessionCount();
135 uint32 queuedClientsNum = sWorld->GetQueuedSessionCount();
136 uint32 maxActiveClientsNum = sWorld->GetMaxActiveSessionCount();
137 uint32 maxQueuedClientsNum = sWorld->GetMaxQueuedSessionCount();
138 std::string uptime = secsToTimeString(sWorld->GetUptime());
139 uint32 updateTime = sWorld->GetUpdateTime();
140 Skyfire::ProcessMemoryUsage processMemory;
141 Skyfire::GetProcessMemoryUsage(processMemory);
142 Skyfire::SystemMemoryUsage systemMemory;
143 Skyfire::GetSystemMemoryUsage(systemMemory);
144
145 handler->PSendSysMessage("Open Source Emulation https://www.projectskyfire.org");
146 handler->PSendSysMessage("www.github.com/ProjectSkyfire/SkyFire_548");
147 handler->PSendSysMessage("revision: %s", SKYFIRE_VER_PRODUCTVERSION_STR);
148 handler->PSendSysMessage(LANG_CONNECTED_PLAYERS, playersNum, maxPlayersNum);
149 handler->PSendSysMessage(LANG_CONNECTED_USERS, activeClientsNum, maxActiveClientsNum, queuedClientsNum, maxQueuedClientsNum);
150 handler->PSendSysMessage(LANG_UPTIME, uptime.c_str());
151 std::string summary = Skyfire::FormatMemoryUsageSummary(processMemory, systemMemory);
152 handler->PSendSysMessage("Memory Summary: %s", summary.c_str());
153 SendRuntimeMetrics(handler);
154 handler->PSendSysMessage(LANG_UPDATE_DIFF, updateTime);
155
156 // Can't use sWorld->ShutdownMsg here in case of console command
157 if (sWorld->IsShuttingDown())
158 handler->PSendSysMessage(LANG_SHUTDOWN_TIMELEFT, secsToTimeString(sWorld->GetShutDownTimeLeft()).c_str());
159
160 return true;
161 }
162
163 static bool HandleServerUptimeCommand(ChatHandler* handler, char const* /*args*/)
164 {
165 std::string uptime = secsToTimeString(sWorld->GetUptime());
166 handler->PSendSysMessage(LANG_UPTIME, uptime.c_str());
167 return true;
168 }
169
170 // Display the 'Message of the day' for the realm
171 static bool HandleServerMotdCommand(ChatHandler* handler, char const* /*args*/)
172 {
173 handler->PSendSysMessage(LANG_MOTD_CURRENT, sWorld->GetMotd());
174 return true;
175 }
176
177 static bool HandleServerPLimitCommand(ChatHandler* handler, char const* args)
178 {
179 if (*args)
180 {
181 char* paramStr = strtok((char*)args, " ");
182 if (!paramStr)
183 return false;
184
185 int32 limit = strlen(paramStr);
186
187 if (strncmp(paramStr, "player", limit) == 0)
188 sWorld->SetPlayerSecurityLimit(AccountTypes::SEC_PLAYER);
189 else if (strncmp(paramStr, "moderator", limit) == 0)
190 sWorld->SetPlayerSecurityLimit(AccountTypes::SEC_MODERATOR);
191 else if (strncmp(paramStr, "gamemaster", limit) == 0)
192 sWorld->SetPlayerSecurityLimit(AccountTypes::SEC_GAMEMASTER);
193 else if (strncmp(paramStr, "administrator", limit) == 0)
194 sWorld->SetPlayerSecurityLimit(AccountTypes::SEC_ADMINISTRATOR);
195 else if (strncmp(paramStr, "reset", limit) == 0)
196 {
197 sWorld->SetPlayerAmountLimit(sConfigMgr->GetIntDefault("PlayerLimit", 100));
198 sWorld->LoadDBAllowedSecurityLevel();
199 }
200 else
201 {
202 int32 value = atoi(paramStr);
203 if (value < 0)
204 sWorld->SetPlayerSecurityLimit(AccountTypes(-value));
205 else
206 sWorld->SetPlayerAmountLimit(uint32(value));
207 }
208 }
209
210 uint32 playerAmountLimit = sWorld->GetPlayerAmountLimit();
211 AccountTypes allowedAccountType = sWorld->GetPlayerSecurityLimit();
212 char const* secName = "";
213 switch (allowedAccountType)
214 {
216 secName = "Player";
217 break;
219 secName = "Moderator";
220 break;
222 secName = "Gamemaster";
223 break;
225 secName = "Administrator";
226 break;
227 default:
228 secName = "<unknown>";
229 break;
230 }
231 handler->PSendSysMessage("Player limits: amount %u, min. security level %s.", playerAmountLimit, secName);
232
233 return true;
234 }
235
236 static bool HandleServerShutDownCancelCommand(ChatHandler* /*handler*/, char const* /*args*/)
237 {
238 sWorld->ShutdownCancel();
239
240 return true;
241 }
242
243 static bool HandleServerShutDownCommand(ChatHandler* /*handler*/, char const* args)
244 {
245 if (!*args)
246 return false;
247
248 char* timeStr = strtok((char*)args, " ");
249 char* exitCodeStr = strtok(NULL, "");
250
251 int32 time = atoi(timeStr);
252
253 // Prevent interpret wrong arg value as 0 secs shutdown time
254 if ((time == 0 && (timeStr[0] != '0' || timeStr[1] != '\0')) || time < 0)
255 return false;
256
257 if (exitCodeStr)
258 {
259 int32 exitCode = atoi(exitCodeStr);
260
261 // Handle atoi() errors
262 if (exitCode == 0 && (exitCodeStr[0] != '0' || exitCodeStr[1] != '\0'))
263 return false;
264
265 // Exit code should be in range of 0-125, 126-255 is used
266 // in many shells for their own return codes and code > 255
267 // is not supported in many others
268 if (exitCode < 0 || exitCode > 125)
269 return false;
270
271 sWorld->ShutdownServ(time, 0, exitCode);
272 }
273 else
274 sWorld->ShutdownServ(time, 0, SHUTDOWN_EXIT_CODE);
275
276 return true;
277 }
278
279 static bool HandleServerRestartCommand(ChatHandler* /*handler*/, char const* args)
280 {
281 if (!*args)
282 return false;
283
284 char* timeStr = strtok((char*)args, " ");
285 char* exitCodeStr = strtok(NULL, "");
286
287 int32 time = atoi(timeStr);
288
289 // Prevent interpret wrong arg value as 0 secs shutdown time
290 if ((time == 0 && (timeStr[0] != '0' || timeStr[1] != '\0')) || time < 0)
291 return false;
292
293 if (exitCodeStr)
294 {
295 int32 exitCode = atoi(exitCodeStr);
296
297 // Handle atoi() errors
298 if (exitCode == 0 && (exitCodeStr[0] != '0' || exitCodeStr[1] != '\0'))
299 return false;
300
301 // Exit code should be in range of 0-125, 126-255 is used
302 // in many shells for their own return codes and code > 255
303 // is not supported in many others
304 if (exitCode < 0 || exitCode > 125)
305 return false;
306
307 sWorld->ShutdownServ(time, SHUTDOWN_MASK_RESTART, exitCode);
308 }
309 else
310 sWorld->ShutdownServ(time, SHUTDOWN_MASK_RESTART, RESTART_EXIT_CODE);
311
312 return true;
313 }
314
315 static bool HandleServerRestartTimeCommand(ChatHandler* /*handler*/, char const* args)
316 {
317 if (!*args)
318 return false;
319
320 char* timeStr = strtok((char*)args, " ");
321 char* exitCodeStr = strtok(NULL, "");
322
323 uint32 delaySeconds = 0;
325 return false;
326
327 if (exitCodeStr)
328 {
329 int32 exitCode = atoi(exitCodeStr);
330
331 // Handle atoi() errors
332 if (exitCode == 0 && (exitCodeStr[0] != '0' || exitCodeStr[1] != '\0'))
333 return false;
334
335 // Exit code should be in range of 0-125, 126-255 is used
336 // in many shells for their own return codes and code > 255
337 // is not supported in many others
338 if (exitCode < 0 || exitCode > 125)
339 return false;
340
341 sWorld->ShutdownServ(delaySeconds, SHUTDOWN_MASK_RESTART, exitCode);
342 }
343 else
344 sWorld->ShutdownServ(delaySeconds, SHUTDOWN_MASK_RESTART, RESTART_EXIT_CODE);
345
346 return true;
347 }
348
349 static bool HandleServerIdleRestartCommand(ChatHandler* /*handler*/, char const* args)
350 {
351 if (!*args)
352 return false;
353
354 char* timeStr = strtok((char*)args, " ");
355 char* exitCodeStr = strtok(NULL, "");
356
357 int32 time = atoi(timeStr);
358
359 // Prevent interpret wrong arg value as 0 secs shutdown time
360 if ((time == 0 && (timeStr[0] != '0' || timeStr[1] != '\0')) || time < 0)
361 return false;
362
363 if (exitCodeStr)
364 {
365 int32 exitCode = atoi(exitCodeStr);
366
367 // Handle atoi() errors
368 if (exitCode == 0 && (exitCodeStr[0] != '0' || exitCodeStr[1] != '\0'))
369 return false;
370
371 // Exit code should be in range of 0-125, 126-255 is used
372 // in many shells for their own return codes and code > 255
373 // is not supported in many others
374 if (exitCode < 0 || exitCode > 125)
375 return false;
376
377 sWorld->ShutdownServ(time, SHUTDOWN_MASK_RESTART | SHUTDOWN_MASK_IDLE, exitCode);
378 }
379 else
381 return true;
382 }
383
384 static bool HandleServerIdleShutDownCommand(ChatHandler* /*handler*/, char const* args)
385 {
386 if (!*args)
387 return false;
388
389 char* timeStr = strtok((char*)args, " ");
390 char* exitCodeStr = strtok(NULL, "");
391
392 int32 time = atoi(timeStr);
393
394 // Prevent interpret wrong arg value as 0 secs shutdown time
395 if ((time == 0 && (timeStr[0] != '0' || timeStr[1] != '\0')) || time < 0)
396 return false;
397
398 if (exitCodeStr)
399 {
400 int32 exitCode = atoi(exitCodeStr);
401
402 // Handle atoi() errors
403 if (exitCode == 0 && (exitCodeStr[0] != '0' || exitCodeStr[1] != '\0'))
404 return false;
405
406 // Exit code should be in range of 0-125, 126-255 is used
407 // in many shells for their own return codes and code > 255
408 // is not supported in many others
409 if (exitCode < 0 || exitCode > 125)
410 return false;
411
412 sWorld->ShutdownServ(time, SHUTDOWN_MASK_IDLE, exitCode);
413 }
414 else
415 sWorld->ShutdownServ(time, SHUTDOWN_MASK_IDLE, SHUTDOWN_EXIT_CODE);
416
417 return true;
418 }
419
420 // Exit the realm
421 static bool HandleServerExitCommand(ChatHandler* handler, char const* /*args*/)
422 {
425 return true;
426 }
427
428 // Define the 'Message of the day' for the realm
429 static bool HandleServerSetMotdCommand(ChatHandler* handler, char const* args)
430 {
431 sWorld->SetMotd(args);
432 handler->PSendSysMessage(LANG_MOTD_NEW, args);
433 return true;
434 }
435
436 // Set whether we accept new clients
437 static bool HandleServerSetClosedCommand(ChatHandler* handler, char const* args)
438 {
439 if (strncmp(args, "on", 3) == 0)
440 {
442 sWorld->SetClosed(true);
443 return true;
444 }
445 else if (strncmp(args, "off", 4) == 0)
446 {
448 sWorld->SetClosed(false);
449 return true;
450 }
451
453 handler->SetSentErrorMessage(true);
454 return false;
455 }
456
457 // Set the level of logging
458 static bool HandleServerSetLogLevelCommand(ChatHandler* /*handler*/, char const* args)
459 {
460 if (!*args)
461 return false;
462
463 char* type = strtok((char*)args, " ");
464 char* name = strtok(NULL, " ");
465 char* level = strtok(NULL, " ");
466
467 if (!type || !name || !level || *name == '\0' || *level == '\0' || (*type != 'a' && *type != 'l'))
468 return false;
469
470 sLog->SetLogLevel(name, level, *type == 'l');
471 return true;
472 }
473
474 // set diff time record interval
475 static bool HandleServerSetDiffTimeCommand(ChatHandler* /*handler*/, char const* args)
476 {
477 if (!*args)
478 return false;
479
480 char* newTimeStr = strtok((char*)args, " ");
481 if (!newTimeStr)
482 return false;
483
484 int32 newTime = atoi(newTimeStr);
485 if (newTime < 0)
486 return false;
487
488 sWorld->SetRecordDiffInterval(newTime);
489 printf("Record diff every %u ms\n", newTime);
490
491 return true;
492 }
493};
494
AccountTypes
Definition Common.h:129
@ SEC_MODERATOR
Definition Common.h:131
@ SEC_ADMINISTRATOR
Definition Common.h:133
@ SEC_GAMEMASTER
Definition Common.h:132
#define sConfigMgr
Definition Config.h:64
std::int32_t int32
Definition Define.h:73
#define UI64FMTD
Definition Define.h:64
std::uint32_t uint32
Definition Define.h:77
#define OVERRIDE
Definition Define.h:60
@ LANG_MOTD_CURRENT
Definition Language.h:69
@ LANG_UPDATE_DIFF
Definition Language.h:32
@ LANG_COMMAND_EXIT
Definition Language.h:858
@ LANG_USE_BOL
Definition Language.h:265
@ LANG_CONNECTED_USERS
Definition Language.h:25
@ LANG_WORLD_CLOSED
Definition Language.h:1127
@ LANG_UPTIME
Definition Language.h:26
@ LANG_MOTD_NEW
Definition Language.h:891
@ LANG_WORLD_OPENED
Definition Language.h:1128
@ LANG_CONNECTED_PLAYERS
Definition Language.h:73
@ LANG_SHUTDOWN_TIMELEFT
Definition Language.h:33
#define sLog
Definition Log.h:106
#define sMapMgr
Definition MapManager.h:145
#define sObjectAccessor
std::string secsToTimeString(uint64 timeInSecs, bool shortText, bool hoursOnly)
Definition Util.cpp:127
void PSendSysMessage(const char *format,...) ATTR_PRINTF(2
Definition Chat.cpp:221
void SetSentErrorMessage(bool val)
Definition Chat.h:114
virtual void SendSysMessage(const char *str)
Definition Chat.cpp:153
CommandScript(const char *name)
static void StopNow(uint8 exitcode)
Definition World.h:674
static bool HandleServerShutDownCommand(ChatHandler *, char const *args)
static bool HandleServerUptimeCommand(ChatHandler *handler, char const *)
static bool HandleServerMetricsCommand(ChatHandler *handler, char const *)
static bool HandleServerIdleRestartCommand(ChatHandler *, char const *args)
std::vector< ChatCommand > GetCommands() const OVERRIDE
Definition cs_server.cpp:30
static bool HandleServerMetricsResetCommand(ChatHandler *handler, char const *)
static bool HandleServerSetDiffTimeCommand(ChatHandler *, char const *args)
static bool HandleServerSetMotdCommand(ChatHandler *handler, char const *args)
static bool HandleServerExitCommand(ChatHandler *handler, char const *)
static bool HandleServerCorpsesCommand(ChatHandler *, char const *)
Definition cs_server.cpp:95
static bool HandleServerSetLogLevelCommand(ChatHandler *, char const *args)
static void SendRuntimeMetrics(ChatHandler *handler)
static bool HandleServerPLimitCommand(ChatHandler *handler, char const *args)
static bool HandleServerRestartTimeCommand(ChatHandler *, char const *args)
static bool HandleServerMotdCommand(ChatHandler *handler, char const *)
static bool HandleServerSetClosedCommand(ChatHandler *handler, char const *args)
static bool HandleServerInfoCommand(ChatHandler *handler, char const *)
static bool HandleServerIdleShutDownCommand(ChatHandler *, char const *args)
static bool HandleServerRestartCommand(ChatHandler *, char const *args)
static bool HandleServerShutDownCancelCommand(ChatHandler *, char const *)
void AddSC_server_commandscript()
#define sWorld
Definition World.h:910
@ SHUTDOWN_MASK_RESTART
Definition World.h:58
@ SHUTDOWN_MASK_IDLE
Definition World.h:59
@ RESTART_EXIT_CODE
Definition World.h:66
@ SHUTDOWN_EXIT_CODE
Definition World.h:64
RuntimeMetrics & GetRuntimeMetrics()
std::vector< std::string > FormatRuntimeMetricLines(RuntimeMetricsSnapshot const &snapshot)
bool CalculateRestartDelay(char const *text, uint32 currentSecondsOfDay, uint32 &delaySeconds)
bool GetProcessMemoryUsage(ProcessMemoryUsage &usage)
bool GetSystemMemoryUsage(SystemMemoryUsage &usage)
std::string FormatMemoryUsageSummary(ProcessMemoryUsage const &processUsage, SystemMemoryUsage const &systemUsage)
@ RBAC_PERM_COMMAND_SERVER_SHUTDOWN
Definition RBAC.h:622
@ RBAC_PERM_COMMAND_SERVER_SET_LOGLEVEL
Definition RBAC.h:620
@ RBAC_PERM_COMMAND_SERVER_RESTART_CANCEL
Definition RBAC.h:616
@ RBAC_PERM_COMMAND_SERVER_SET
Definition RBAC.h:617
@ RBAC_PERM_COMMAND_SERVER_EXIT
Definition RBAC.h:608
@ RBAC_PERM_COMMAND_SERVER_RESTART
Definition RBAC.h:615
@ RBAC_PERM_COMMAND_SERVER_PLIMIT
Definition RBAC.h:614
@ RBAC_PERM_COMMAND_SERVER_IDLESHUTDOWN_CANCEL
Definition RBAC.h:612
@ RBAC_PERM_COMMAND_SERVER_SET_DIFFTIME
Definition RBAC.h:619
@ RBAC_PERM_COMMAND_SERVER_UPTIME
Definition RBAC.h:664
@ RBAC_PERM_COMMAND_SERVER_SHUTDOWN_CANCEL
Definition RBAC.h:623
@ RBAC_PERM_COMMAND_SERVER_IDLERESTART_CANCEL
Definition RBAC.h:610
@ RBAC_PERM_COMMAND_SERVER
Definition RBAC.h:606
@ RBAC_PERM_COMMAND_SERVER_MOTD
Definition RBAC.h:624
@ RBAC_PERM_COMMAND_SERVER_SET_CLOSED
Definition RBAC.h:618
@ RBAC_PERM_COMMAND_SERVER_SET_MOTD
Definition RBAC.h:621
@ RBAC_PERM_COMMAND_SERVER_INFO
Definition RBAC.h:613
@ RBAC_PERM_COMMAND_SERVER_IDLERESTART
Definition RBAC.h:609
@ RBAC_PERM_COMMAND_SERVER_IDLESHUTDOWN
Definition RBAC.h:611
@ RBAC_PERM_COMMAND_SERVER_CORPSES
Definition RBAC.h:607