Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_DedicatedServerPlugin.c
Go to the documentation of this file.
1#ifdef WORKBENCH
2[WorkbenchPluginAttribute(name: "Dedicated Server Tool", shortcut: "Ctrl+Shift+D", wbModules: { "WorldEditor" }, awesomeFontCode: 0xF233)]
3class SCR_DedicatedServerPlugin : WorldEditorPlugin
4{
5 /*
6 Category: Server
7 */
8
9 [Attribute(desc: "Server configuration. Dedicated server cannot be launched without this!", category: "Server")]
10 protected ref DedicatedServerPluginCLI m_Config;
11
12 [Attribute("ArmaReforgerServer.exe", UIWidgets.FileNamePicker, desc: "Executable file used to start the server.", params: "exe FileNameFormat=absolute", category: "Server")]
13 protected string m_sExecutable;
14
15 [Attribute("", desc: "Profile used on the server.", category: "Server")]
16 protected string m_sProfile;
17
18 [Attribute("0", desc: "Suppresses all sorts of errors (like asserts), so the game continues without stalling and disconnecting clients.", category: "Server")]
19 protected bool m_bNoThrow;
20
21 [Attribute("", uiwidget: UIWidgets.ComboBox, desc: "Enable Backend logs\n- Basic: Turn on basic logs\n- Http: Turn on logging of Http Response & Requests\n- File: Turn on saving of related (mostly JSON) files send and/or recieved from backend into logs folder and subfolder .backend\n- Trace: Turn on logging of inner Http comm - valid only for libcurl (windows ATM)", category: "Server", enums: { ParamEnum("None", "0"), ParamEnum("Basic", "1"), ParamEnum("Http", "2"), ParamEnum("File", "3"), ParamEnum("Trace", "4")})]
22 protected int m_iLogBackend;
23
24 [Attribute("", uiwidget: UIWidgets.ComboBox, desc: "llows manual rerouting to one of our Backend Environments (only in internal version, retail is baked to production system).\n- Dev: Internal development environment\n- Preprod: Preproduction\n- Submission: Submission (preproduction RC candidate environment for testing by QA)\n- Production: Production, this mean players\n- Local: For working without deployed version on your machine", category: "Server", enums: { ParamEnum("None", "0"), ParamEnum("Dev", "1"), ParamEnum("Preprod", "2"), ParamEnum("Submission", "3"), ParamEnum("Production", "4"), ParamEnum("Local", "5")})]
25 protected int m_iBackendEnv;
26
27 [Attribute("30", desc: "Maximum FPS on the server. When 0, no limit will be set.", category: "Server")]
28 protected int m_iMaxFPS;
29
30 [Attribute(LogLevel.NORMAL.ToString(), desc: "Set the highest shown log level.\nAll others below in the list will be included as well\n(e.g., VERBOSE also enables DEBUG, NORMAL, WARNING, etc, but not SPAM).", uiwidget: UIWidgets.ComboBox, category: "Server", enumType: LogLevel)]
31 protected int m_iLogLevel;
32
33 [Attribute(desc: "Additional command line params.", category: "Server")]
34 protected string m_sParams;
35
36 /*
37 Category: Peers
38 */
39
40 [Attribute(desc: "Run peers defined by the PeerTool.", category: "Peers")]
41 protected bool m_bRunPeers;
42
43 [Attribute("ArmaReforger.exe", UIWidgets.FileNamePicker, desc: "Peer exe path", params: "exe FileNameFormat=absolute", category: "Peers")]
44 protected string m_sPeerExecutable;
45
46 [Attribute(desc: "Peers configuration.", category: "Peers")]
47 protected ref array<ref PeerConfig> m_aPeersConfig;
48
49 protected ProcessHandle m_ServerHandle;
50
51 //------------------------------------------------------------------------------------------------
52 protected string GetAddonsDirCLI()
53 {
54 string addonsDir;
55 System.GetCLIParam("addonsDir", addonsDir);
56 return addonsDir;
57 }
58
59 //------------------------------------------------------------------------------------------------
60 protected string GetAddonsCLI()
61 {
62 string addonIDs;
63
64 array<string> addonsGUIDs = {};
65 GameProject.GetLoadedAddons(addonsGUIDs);
66
67 foreach (string GUID : addonsGUIDs)
68 {
69 if (GameProject.IsVanillaAddon(GUID))
70 continue;
71
72 if (!addonIDs.IsEmpty())
73 addonIDs += ",";
74
75 addonIDs += GameProject.GetAddonID(GUID);
76 }
77
78 return addonIDs;
79 }
80
81 //------------------------------------------------------------------------------------------------
82 override void Run()
83 {
84 if (!Workbench.ScriptDialog("Start Dedicated Server", "Configure dedicated server before running it. ", this))
85 return;
86
87 WorldEditor worldEditor = Workbench.GetModule(WorldEditor);
88 WorldEditorAPI api = worldEditor.GetApi();
89
90 //--- Generate run command
91 string gproj = Workbench.GetCurrentGameProjectFile();
92 string process = string.Format("%1 -gproj=\"%2\"", m_sExecutable, gproj);
93
94 string configParam;
95 if (m_Config && m_Config.GetCLI(configParam, api))
96 {
97 process += " " + configParam;
98 }
99 else
100 {
101 Print("Cannot start dedicated server, 'Config' setting is incomplete!", LogLevel.WARNING);
102 return;
103 }
104
105 string addonsDir = GetAddonsDirCLI();
106 if (!addonsDir.IsEmpty())
107 process += " -addonsDir " + addonsDir;
108
109 string addonIDs = GetAddonsCLI();
110 if (!addonIDs.IsEmpty())
111 process += " -addons " + addonIDs;
112
113 if (m_sProfile)
114 process += string.Format(" -profile %1", m_sProfile);
115
116 if (m_bNoThrow)
117 process += " -nothrow";
118
119 switch (m_iLogBackend)
120 {
121 case 1: process += " -backendLog"; break;
122 case 2: process += " -backendLog Http"; break;
123 case 3: process += " -backendLog File"; break;
124 case 4: process += " -backendLog Trace"; break;
125 }
126
127 switch (m_iBackendEnv)
128 {
129 case 1: process += " -backendEnv Dev"; break;
130 case 2: process += " -backendEnv Preprod"; break;
131 case 3: process += " -backendEnv Submission"; break;
132 case 4: process += " -backendEnv Production"; break;
133 case 5: process += " -backendEnv Local"; break;
134 }
135
136 if (m_iMaxFPS > 0)
137 process += string.Format(" -maxFPS %1", m_iMaxFPS);
138
139 if (m_iLogLevel != LogLevel.NORMAL)
140 process += string.Format(" -logLevel %1", typename.EnumToString(LogLevel, m_iLogLevel));
141
142 if (m_sParams)
143 process += " " + m_sParams;
144
145 //--- Start dedicated server
146 m_ServerHandle = Workbench.RunProcess(process);
147 Print(string.Format("Starting dedicated server: %1", process), LogLevel.NORMAL);
148
149 //--- Connect to the server
150 if (!m_bRunPeers)
151 return;
152
153 int profileIndex;
154
155 foreach (PeerConfig conf : m_aPeersConfig)
156 {
157 if (!conf.Enabled)
158 continue;
159
160 profileIndex++; // start indexing peers from 1
161 string sCmd = m_sPeerExecutable + " -gproj \"" + gproj + "\" ";
162
163 if (!addonsDir.IsEmpty())
164 sCmd += "-addonsDir " + addonsDir + " ";
165
166 if (!addonIDs.IsEmpty())
167 sCmd += "-addons " + addonIDs + " ";
168
169 if (conf.Windowed)
170 sCmd += "-window ";
171
172 if (conf.X != -1)
173 sCmd += "-posX " + conf.X + " ";
174
175 if (conf.Y != -1)
176 sCmd += "-posY " + conf.Y + " ";
177
178 if (conf.Width != -1)
179 sCmd += "-screenWidth " + conf.Width + " ";
180
181 if (conf.Height != -1)
182 sCmd += "-screenHeight " + conf.Height + " ";
183
184 if (conf.MaxFPS > 0)
185 sCmd += "-maxFPS " + conf.MaxFPS + " ";
186
187 if (conf.ForceUpdate)
188 sCmd += "-forceupdate ";
189
190 if (conf.NoFocus)
191 sCmd += "-nofocus ";
192
193 if (conf.RplAutoJoin)
194 sCmd += "-client ";
195
196 if (conf.RplAutoReconnect)
197 sCmd += "-rpl-reconnect ";
198
199 if (conf.RplDisableTimeout)
200 sCmd += "-rpl-timeout-disable ";
201
202 if (conf.Profile)
203 sCmd += "-profile " + conf.Profile + profileIndex.ToString() + " ";
204
205 if (conf.Params)
206 sCmd += conf.Params + " ";
207
208 Print("Running command: " + sCmd, LogLevel.NORMAL);
209 conf.Handle = Workbench.RunProcess(sCmd);
210 if (!conf.Handle)
211 Print("Peer #" + profileIndex + " couldn't run. Check if your PeerExecutable or other settings are correct", LogLevel.ERROR);
212 }
213 }
214
215 //------------------------------------------------------------------------------------------------
216 override void OnGameModeEnded()
217 {
218 // Close any connected peers
219 foreach (PeerConfig conf : m_aPeersConfig)
220 {
221 if (!conf.Handle) // what if the game mode wasn't the PeerTool?
222 continue;
223
224 Workbench.KillProcess(conf.Handle);
225 conf.Handle = null;
226 }
227
228 // Close the server when returning from play mode
229 if (m_ServerHandle)
230 Workbench.KillProcess(m_ServerHandle);
231 }
232
233 //------------------------------------------------------------------------------------------------
234 [ButtonAttribute("Run", true)]
235 protected bool ButtonRun()
236 {
237 return true;
238 }
239
240 //------------------------------------------------------------------------------------------------
241 [ButtonAttribute("Close")]
242 protected bool ButtonClose()
243 {
244 return false;
245 }
246}
247
248// TODO: SCR_
250class DedicatedServerPluginCLI
251{
252 //------------------------------------------------------------------------------------------------
256 bool GetCLI(out string outParam, WorldEditorAPI api);
257}
258
259// TODO: SCR_
261class DedicatedServerPluginCLI_Server : DedicatedServerPluginCLI
262{
263 [Attribute(desc: "World which the server will start.\nWhen empty, currently opened world will be used.", uiwidget: UIWidgets.ResourceNamePicker, params: "ent")]
264 protected ResourceName m_World;
265
266 [Attribute(desc: "Mission configuration, can enable settings like metabolism / vehicles, set loading screen image, etc.", uiwidget: UIWidgets.ResourceNamePicker, params: "conf class=SCR_MissionHeader")]
267 protected ResourceName m_MissionHeader;
268
269 [Attribute(desc: "Systems configuration to be run if not using the .gproj default one.", uiwidget: UIWidgets.ResourceNamePicker, params: "conf class=SystemSettings")]
270 protected ResourceName m_SystemsConfig;
271
272 [Attribute(desc: "Optional password for logging-in as administrator (in game, type '#login <password>' in chat)")]
273 protected string m_sAdminPassword;
274
275 //------------------------------------------------------------------------------------------------
276 override bool GetCLI(out string outParam, WorldEditorAPI api)
277 {
278 ResourceName worldPath = m_World;
279 if (!worldPath)
280 api.GetWorldPath(worldPath);
281
282 outParam = string.Format("-server \"%1\"", worldPath.GetPath());
283
284 if (m_MissionHeader)
285 outParam += string.Format(" -MissionHeader \"%1\"", m_MissionHeader.GetPath());
286
287 if (m_SystemsConfig)
288 outParam += string.Format(" -worldSystemsConfig \"%1\"", m_SystemsConfig.GetPath());
289
290 if (m_sAdminPassword)
291 outParam += string.Format(" -adminPassword %1", m_sAdminPassword);
292
293 return !worldPath.IsEmpty();
294 }
295}
296
297// TODO: SCR_
299class DedicatedServerPluginCLI_Config : DedicatedServerPluginCLI
300{
301 [Attribute(desc: "JSON server configuration file. Does not work when the game is running with local (i.e., non-workshop) addons!", uiwidget: UIWidgets.ResourceNamePicker, params: "json")]
302 protected ResourceName m_Config;
303
304 //------------------------------------------------------------------------------------------------
305 override bool GetCLI(out string outParam, WorldEditorAPI api)
306 {
307 //--- Convert to absolute path, relative ResourceName is in the wrong format
308 string absPath;
309 Workbench.GetAbsolutePath(m_Config.GetPath(), absPath);
310
311 outParam = string.Format("-config \"%1\"", absPath);
312 return !m_Config.IsEmpty();
313 }
314}
315#endif // WORKBENCH
GenerateFlowMaps WorkbenchPlugin WorkbenchPluginAttribute("Regenerate river flow-maps", "Generate and save/overwrite river flow-maps", "", "", {"WorldEditor"}, "", 0xf773)
Definition FlowmapTool.c:59
SCR_AIAnimation_Loitering BaseContainerProps
Commanding menu commanding element class.
override void Run()
Configs ServerBrowser KickDialogs conf
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
class WorkbenchDialog_AbortRetryIgnore ButtonAttribute("OK", true)
proto void Print(void var, LogLevel level=LogLevel.NORMAL)
Prints content of variable to console/log.
LogLevel
Enum with severity of the logging message.
Definition LogLevel.c:14
SCR_FieldOfViewSettings Attribute