Skip to content

Commit c3aebc3

Browse files
authored
RCON Support (#96)
* Added RCON dotnet submodule * RCON Manager * RCON works * Switched inter-thread passing from tasks callbacks to BlockingCollection * Cleanup * Config based rcon port and password * RCON is disabled by default in config * Added SanAndreasUnity.RCON namespace to CommandInterpreter * Pass command to main thread first and report progress afterwards * Minor cleanup * Removed InvalidOperationException as it was never possible * Moved OnLoaderFinished code in RCONManager * Added RCONManager script to prefab * Added meta files
1 parent 29d5a04 commit c3aebc3

File tree

10 files changed

+197
-3
lines changed

10 files changed

+197
-3
lines changed

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,6 @@
44
[submodule "Assets/UnityStandardAssets"]
55
path = Assets/UnityStandardAssets
66
url = https://github.com/GTA-ASM/UnityStandardAssets
7+
[submodule "Assets/RCONdotnet"]
8+
path = Assets/RCONdotnet
9+
url = https://github.com/undbsd/rcon-dotnet

Assets/Prefabs/GameManager.prefab

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ GameObject:
2424
- component: {fileID: 1318502437576191535}
2525
- component: {fileID: 7442340376164908290}
2626
- component: {fileID: 8446601354455743255}
27+
- component: {fileID: 5853763562556677784}
2728
m_Layer: 0
2829
m_Name: GameManager
2930
m_TagString: Untagged
@@ -299,3 +300,15 @@ MonoBehaviour:
299300
type: 3}
300301
messagesContainer: {fileID: 0}
301302
messagePoolSize: 10
303+
--- !u!114 &5853763562556677784
304+
MonoBehaviour:
305+
m_ObjectHideFlags: 0
306+
m_CorrespondingSourceObject: {fileID: 0}
307+
m_PrefabInstance: {fileID: 0}
308+
m_PrefabAsset: {fileID: 0}
309+
m_GameObject: {fileID: 1297494511425690}
310+
m_Enabled: 1
311+
m_EditorHideFlags: 0
312+
m_Script: {fileID: 11500000, guid: c77317cdc437f244b8d409c229aa2e95, type: 3}
313+
m_Name:
314+
m_EditorClassIdentifier:

Assets/RCONdotnet

Submodule RCONdotnet added at b5e93d9

Assets/RCONdotnet.meta

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Assets/Resources/config.json

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"sv_max_connections": 32,
1111
"sv_port": 14242,
1212

13-
"game_dir" : "",
13+
"game_dir": "",
1414

1515
"archive_paths": [
1616
"${game_dir}/models/gta3.img",
@@ -35,10 +35,13 @@
3535
"water_path": "${game_dir}/data/water.dat",
3636
"car_colors_path": "${game_dir}/data/carcols.dat",
3737
"anim_groups_paths": [
38-
"${game_dir}/data/animgrp.dat",
38+
"${game_dir}/data/animgrp.dat"
3939
],
4040
"weapons_path": "${game_dir}/data/weapon.dat",
4141

4242
"dontLoadTextures": false,
43-
43+
44+
"RCON_enabled": false,
45+
"RCON_password": "super_secret_password",
46+
"RCON_port": 25575
4447
}

Assets/Scripts/RCON.meta

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
using UnityEngine;
5+
6+
namespace SanAndreasUnity.RCON
7+
{
8+
public class CommandInterpreter
9+
{
10+
public static String Interpret(String command)
11+
{
12+
string[] words = command.Split(' ');
13+
14+
if (command == "heartbeat")
15+
{
16+
// Implement heartbeat ping
17+
return "Heartbeat was sent to master server";
18+
}
19+
20+
if (command == "help")
21+
{
22+
return "The available commands for now are heartbeat, announce and help";
23+
}
24+
25+
if (words[0] == "announce")
26+
{
27+
String announcement = String.Join(" ", words, 1, words.Length - 1);
28+
SanAndreasUnity.Chat.ChatManager.SendChatMessageToAllPlayersAsServer(announcement);
29+
return "Server : " + announcement;
30+
}
31+
32+
return "Unknown command";
33+
}
34+
}
35+
36+
}

Assets/Scripts/RCON/CommandInterpreter.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Assets/Scripts/RCON/RCONManager.cs

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
using Rcon;
2+
using Rcon.Events;
3+
using SanAndreasUnity.Net;
4+
using SanAndreasUnity.Utilities;
5+
using System;
6+
using System.Collections.Concurrent;
7+
using System.ComponentModel;
8+
using System.Threading.Tasks;
9+
using UnityEngine;
10+
11+
namespace SanAndreasUnity.RCON
12+
{
13+
public class RCONManager : MonoBehaviour
14+
{
15+
// Todo : set these from config
16+
private static String password;
17+
private static int portNumber;
18+
19+
// Objects used to pass commands and responses between threads
20+
private static BlockingCollection<String> mainToSec = new BlockingCollection<String>(1);
21+
private static BlockingCollection<String> secToMain = new BlockingCollection<String>(1);
22+
23+
private static BackgroundWorker workerInstance = null;
24+
25+
public static void StartServer()
26+
{
27+
password = Config.Get<string>("RCON_password");
28+
portNumber = Config.Get<int>("RCON_port");
29+
30+
if (workerInstance != null)
31+
return;
32+
33+
workerInstance = new BackgroundWorker();
34+
35+
workerInstance.DoWork += new DoWorkEventHandler( worker_doWork );
36+
workerInstance.ProgressChanged += new ProgressChangedEventHandler( worker_progressChanged );
37+
workerInstance.WorkerReportsProgress = true;
38+
// workerInstance.WorkerSupportsCancellation = true;
39+
40+
workerInstance.RunWorkerAsync(); // Call the background worker
41+
}
42+
43+
#region Code that runs in the RCON Server Thread
44+
private static void worker_doWork(object sender, DoWorkEventArgs e)
45+
{
46+
using (RconServer server = new RconServer(password, portNumber))
47+
{
48+
server.OnClientCommandReceived += Server_OnClientCommandReceived;
49+
server.OnClientConnected += Server_OnClientConnected;
50+
server.OnClientAuthenticated += Server_OnClientAuthenticated;
51+
server.OnClientDisconnected += Server_OnClientDisconnected;
52+
server.Start();
53+
}
54+
}
55+
static void Server_OnClientAuthenticated(object sender, ClientAuthenticatedEventArgs e)
56+
{
57+
// Console.WriteLine("{0} authenticated", e.Client.Client.LocalEndPoint);
58+
}
59+
static void Server_OnClientDisconnected(object sender, ClientDisconnectedEventArgs e)
60+
{
61+
// Console.WriteLine("{0} disconnected", e.EndPoint);
62+
}
63+
static void Server_OnClientConnected(object sender, ClientConnectedEventArgs e)
64+
{
65+
// Console.WriteLine("{0} connected", e.Client.Client.LocalEndPoint);
66+
}
67+
static string Server_OnClientCommandReceived(object sender, ClientSentCommandEventArgs e)
68+
{
69+
secToMain.Add(e.Command); // Pass the command to the main thread
70+
71+
workerInstance.ReportProgress(0); //Report our progress to the main thread
72+
73+
String commandResult = "Command didn't process correctly"; // default value
74+
75+
commandResult = mainToSec.Take();
76+
77+
return commandResult;
78+
}
79+
#endregion
80+
81+
// Runs in main thread
82+
private static void worker_progressChanged(object sender, ProgressChangedEventArgs e)
83+
{
84+
String command = "unknown";
85+
86+
command = secToMain.Take();
87+
88+
mainToSec.Add(CommandInterpreter.Interpret(command));
89+
}
90+
91+
void OnLoaderFinished()
92+
{
93+
if (NetStatus.IsServer)
94+
{
95+
if (Config.Get<bool>("RCON_enabled"))
96+
StartServer();
97+
}
98+
}
99+
}
100+
}

Assets/Scripts/RCON/RCONManager.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)