Skip to content

Commit c57af2a

Browse files
authored
Add files via upload
1 parent 2d50779 commit c57af2a

File tree

19 files changed

+729
-0
lines changed

19 files changed

+729
-0
lines changed

DemoRecorder/DemoRecorder.cs

Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
using CounterStrikeSharp.API;
2+
using CounterStrikeSharp.API.Core;
3+
using CounterStrikeSharp.API.Core.Attributes.Registration;
4+
using CounterStrikeSharp.API.Modules.Admin;
5+
using CounterStrikeSharp.API.Modules.Commands;
6+
using CounterStrikeSharp.API.Modules.Config;
7+
using CounterStrikeSharp.API.Modules.Utils;
8+
using CounterStrikeSharp.API.Modules.Cvars;
9+
using Microsoft.Extensions.Logging;
10+
11+
namespace DemoRecorder;
12+
13+
public class DemoRecorder : BasePlugin, IPluginConfig<PluginConfig>
14+
{
15+
public override string ModuleName { get; } = "DemoRecorder";
16+
public override string ModuleVersion { get; } = "1.0.0";
17+
public override string ModuleAuthor { get; } = "SAPSAN";
18+
19+
public PluginConfig Config { get; set; }
20+
21+
public List<CCSPlayerController> connectedPlayers = new List<CCSPlayerController>();
22+
23+
public string g_sDemosName = "",
24+
g_sDemosDir = "",
25+
g_sServerName = "";
26+
27+
public bool g_bChangeMap, bOldState;
28+
29+
public void OnConfigParsed(PluginConfig config)
30+
{
31+
config = ConfigManager.Load<PluginConfig>(ModuleName);
32+
Config = config;
33+
}
34+
35+
public override void Load(bool hotReload)
36+
{
37+
RegisterEventHandler<EventCsIntermission>(OnEventCsIntermissionPost);
38+
RegisterListener<Listeners.OnMapStart>(OnMapStartHandler);
39+
RegisterListener<Listeners.OnMapEnd>(OnMapEndHandler);
40+
41+
g_sDemosDir = Directory.GetCurrentDirectory().Replace("bin/linuxsteamrt64", "");
42+
Directory.SetCurrentDirectory(g_sDemosDir);
43+
44+
g_sServerName = ConVar.Find("hostname").StringValue;
45+
46+
g_sDemosDir += "/csgo/addons/counterstrikesharp/data/" + Config.DemosDir;
47+
48+
if (!Directory.Exists(g_sDemosDir))
49+
{
50+
Logger.LogInformation(">> Create folder for demos: {Folder}.", g_sDemosDir);
51+
52+
Directory.CreateDirectory(g_sDemosDir);
53+
}
54+
g_sDemosName = new string(DateTime.Now.ToString("dd_MM_yyyy_HH_mm") + "-" + Server.MapName + ".dem");
55+
56+
UploadAllDemos();
57+
}
58+
59+
[GameEventHandler(mode: HookMode.Post)]
60+
private HookResult OnEventCsIntermissionPost(EventCsIntermission @event, GameEventInfo info)
61+
{
62+
RecordDemo(false, true);
63+
g_bChangeMap = true;
64+
return HookResult.Continue;
65+
}
66+
67+
[RequiresPermissions("@css/root")]
68+
[ConsoleCommand("css_dr_reload")]
69+
public void OnReloadCommand(CCSPlayerController? controller, CommandInfo info)
70+
{
71+
OnConfigParsed(Config);
72+
Logger.LogInformation(">> Config reloaded!");
73+
controller?.PrintToChat($" {ChatColors.Red}[Demo Recorder] {ChatColors.Default}Config reloaded {ChatColors.Green}success{ChatColors.Default}!");
74+
}
75+
76+
[GameEventHandler]
77+
public HookResult OnPlayerConnectedFull(EventPlayerConnectFull @event, GameEventInfo info)
78+
{
79+
var player = @event.Userid;
80+
81+
if (!player.IsBot)
82+
{
83+
connectedPlayers.Add(player);
84+
85+
if (GetActivePlayerCount() >= Config.MinOnline)
86+
{
87+
RecordDemo(true, false);
88+
}
89+
return HookResult.Continue;
90+
}
91+
return HookResult.Continue;
92+
}
93+
94+
[GameEventHandler]
95+
public HookResult OnPlayerDisconnect(EventPlayerDisconnect @event, GameEventInfo info)
96+
{
97+
var player = @event.Userid;
98+
99+
connectedPlayers.Remove(player);
100+
101+
if (GetActivePlayerCount() < Config.MinOnline)
102+
{
103+
RecordDemo(false, true);
104+
105+
}
106+
return HookResult.Continue;
107+
}
108+
private void OnMapStartHandler(string mapName)
109+
{
110+
g_bChangeMap = false;
111+
g_sDemosName = new string(DateTime.Now.ToString("dd_MM_yyyy_HH_mm") + "-" + mapName + ".dem");
112+
}
113+
114+
private void OnMapEndHandler()
115+
{
116+
if (!g_bChangeMap)
117+
{
118+
RecordDemo(false, false);
119+
g_bChangeMap = true;
120+
}
121+
}
122+
123+
private void RecordDemo(bool bState, bool State)
124+
{
125+
if (g_bChangeMap)
126+
{
127+
return;
128+
}
129+
130+
if (bState && !bOldState)
131+
{
132+
bOldState = true;
133+
134+
Server.ExecuteCommand($"tv_record \"addons/counterstrikesharp/data/{Config.DemosDir}{g_sDemosName}\"");
135+
136+
Logger.LogInformation(">> Recording start ({Name}).", g_sDemosName);
137+
}
138+
else if (!bState && bOldState)
139+
{
140+
bOldState = false;
141+
Server.ExecuteCommand($"tv_stoprecord");
142+
Logger.LogInformation(">> Recording stop ({Name}).", g_sDemosName);
143+
144+
Task.Delay(800).ContinueWith((task) =>
145+
{
146+
UploadDemo(g_sDemosDir + g_sDemosName, State);
147+
});
148+
}
149+
}
150+
151+
async void UploadDemo(string path, bool bUploadOld = false)
152+
{
153+
if (!File.Exists(path)) return;
154+
155+
try
156+
{
157+
string Status = await UploadFile(path);
158+
159+
if(!String.IsNullOrEmpty(Status))
160+
{
161+
Logger.LogInformation(">> Demo upload complete: {File}", path.Split('/').Last());
162+
File.Delete(path);
163+
}
164+
else Logger.LogInformation(">> Demo upload faill: {File}", path.Split('/').Last());
165+
166+
}
167+
catch (Exception ex)
168+
{
169+
Logger.LogInformation(">> HttpPut Exception: {ex}", ex);
170+
}
171+
172+
if(bUploadOld)
173+
{
174+
UploadAllDemos();
175+
}
176+
177+
}
178+
179+
public async Task<string> UploadFile(string path)
180+
{
181+
using var client = new HttpClient();
182+
{
183+
using var content = new StreamContent(File.OpenRead(path));
184+
{
185+
content.Headers.Remove("Content-Type");
186+
content.Headers.Add("Content-Type", "application/octet-stream");
187+
188+
using var req = new HttpRequestMessage(HttpMethod.Put, Config.UploadUrl);
189+
{
190+
req.Headers.Add("Auth", Config.Token);
191+
req.Headers.Add("Server-Name", g_sServerName);
192+
req.Headers.Add("Map-Name", path.Split('-').Last().Replace(".dem", ""));
193+
req.Headers.Add("Demo-Name", path.Split('/').Last());
194+
req.Headers.Add("Demo-ServerId", Config.ServerId.ToString());
195+
req.Headers.Add("Demo-Time", File.GetCreationTime(path).ToString());
196+
197+
req.Content = content;
198+
199+
using HttpResponseMessage resp = await client.SendAsync(req);
200+
{
201+
resp.EnsureSuccessStatusCode();
202+
return await resp.Content.ReadAsStringAsync();
203+
}
204+
}
205+
}
206+
}
207+
}
208+
void UploadAllDemos()
209+
{
210+
foreach (string file in Directory.GetFiles(g_sDemosDir))
211+
{
212+
Logger.LogInformation(">> Try upload old demo: {File}", file);
213+
UploadDemo(file);
214+
}
215+
}
216+
217+
private int GetActivePlayerCount()
218+
{
219+
return connectedPlayers.Count;
220+
}
221+
}

DemoRecorder/DemoRecorder.csproj

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net7.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
</PropertyGroup>
8+
9+
<ItemGroup>
10+
<PackageReference Include="CounterStrikeSharp.API" Version="1.0.142" />
11+
</ItemGroup>
12+
13+
</Project>

DemoRecorder/PluginConfig.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using System.Text.Json.Serialization;
2+
using CounterStrikeSharp.API.Core;
3+
4+
namespace DemoRecorder;
5+
6+
public class PluginConfig : BasePluginConfig
7+
{
8+
[JsonPropertyName("MinOnline")] public int MinOnline { get; set; } = 4;
9+
[JsonPropertyName("ServerId")] public int ServerId { get; set; } = 1;
10+
[JsonPropertyName("DemosDir")] public string DemosDir { get; set; } = "demos/";
11+
[JsonPropertyName("Token")] public string Token { get; set; } = "";
12+
[JsonPropertyName("UploadUrl")] public string UploadUrl { get; set; } = "http://example.com:2053/upload";
13+
}

webserver/Config.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"ssl": false,
3+
"sslCert": "",
4+
"sslKey": "",
5+
6+
"port": "2053",
7+
8+
"database": {
9+
"host": "localhost",
10+
"user": "db_user",
11+
"port": "3306",
12+
"database": "db_name",
13+
"password": "pass"
14+
},
15+
16+
"token": "your_token",
17+
"demos": {
18+
"CleanType": "count",
19+
"DaysOrCount": 500,
20+
"TimeClear": 60,
21+
"UploadDir": "path_toupload_demos"
22+
}
23+
}

webserver/assets/css/app.css

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
*
2+
{
3+
font-family: 'Roboto';
4+
}
5+
6+
#demo__container
7+
{
8+
max-height: 650px;
9+
overflow: hidden;
10+
overflow-y: auto;
11+
}
2.96 KB
Loading
3 KB
Loading

webserver/assets/maps/de_dust2.jpg

3.97 KB
Loading
3.02 KB
Loading
3.47 KB
Loading

0 commit comments

Comments
 (0)