Skip to content

Commit 494b7f3

Browse files
committed
Add ultrakill
1 parent 45d8223 commit 494b7f3

13 files changed

Lines changed: 510 additions & 1 deletion

File tree

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net472</TargetFramework>
5+
<DebugType>Full</DebugType>
6+
<LangVersion>latest</LangVersion>
7+
</PropertyGroup>
8+
9+
10+
<PropertyGroup>
11+
<SteamLibraryPath>C:\Program Files (x86)\Steam\steamapps\common</SteamLibraryPath>
12+
</PropertyGroup>
13+
14+
<ItemGroup>
15+
<Reference Include="Assembly-CSharp">
16+
<HintPath>$(SteamLibraryPath)\ULTRAKILL\ULTRAKILL_Data\Managed\Assembly-CSharp.dll</HintPath>
17+
<PrivateAssets>all</PrivateAssets>
18+
</Reference>
19+
</ItemGroup>
20+
21+
<ItemGroup>
22+
<PackageReference Include="BepInEx.BaseLib" Version="5.4.21" />
23+
<PackageReference Include="UnityEngine" Version="5.6.1" />
24+
<PackageReference Include="UnityEngine.Modules" Version="2022.1.16" />
25+
<PackageReference Include="HarmonyX" Version="2.10.1" />
26+
27+
<PackageReference Update="@(PackageReference)" IncludeAssets="compile;build" />
28+
</ItemGroup>
29+
30+
</Project>
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
using Artemis.Plugins.Games.Ultrakill.GSI.Patches;
2+
using BepInEx;
3+
using HarmonyLib;
4+
using System;
5+
using System.Linq;
6+
using UnityEngine;
7+
using UnityEngine.SceneManagement;
8+
9+
namespace Artemis.Plugins.Games.Ultrakill.GSI
10+
{
11+
[BepInPlugin("com.artemis.gsi", "Artemis GSI", "0.1")]
12+
public class ArtemisGsiPlugin : BaseUnityPlugin
13+
{
14+
public static ArtemisWebClient ArtemisWebClient => _artemisWebClient;
15+
private static ArtemisWebClient _artemisWebClient;
16+
17+
private NewMovement player = null;
18+
private GunControl guns = null;
19+
20+
public void Awake()
21+
{
22+
try
23+
{
24+
_artemisWebClient = new ArtemisWebClient();
25+
}
26+
catch (Exception e)
27+
{
28+
Debug.Log(e);
29+
return;
30+
}
31+
//Harmony harmony = new Harmony("com.artemis.gsi");
32+
// harmony.PatchAll();
33+
34+
Debug.Log("patched artemis");
35+
ArtemisWebClient.StartTimer();
36+
}
37+
38+
public void Start()
39+
{
40+
SceneManager.activeSceneChanged += OnSceneChanged;
41+
}
42+
43+
private void OnSceneChanged(Scene from, Scene to)
44+
{
45+
Debug.Log($"Scene changed to {to.name}");
46+
player = null;
47+
if (SceneManager.GetActiveScene().name.StartsWith("Level") || SceneManager.GetActiveScene().name == "uk_construct")
48+
{
49+
player = FindObjectOfType<NewMovement>();
50+
Debug.Log($"Found player! name:{player.gameObject.name}");
51+
}
52+
if (guns == null)
53+
{
54+
guns = MonoSingleton<GunControl>.Instance;
55+
}
56+
}
57+
58+
public void Update()
59+
{
60+
if (player != null)
61+
{
62+
//Debug.Log($"Health: {player.hp}");
63+
//Debug.Log($"Speed: {player.rb.velocity.magnitude}");
64+
//Debug.Log($"Stamina: {player.boostCharge}");
65+
//Debug.Log($"Jumping: {player.jumping}");
66+
//Debug.Log($"Dead: {player.dead}");
67+
//Debug.Log($"Gun slot: {guns.currentSlot}");
68+
//Debug.Log($"variation: {guns.currentVariation}");
69+
70+
ArtemisPlayer.Health = player.hp;
71+
ArtemisPlayer.Speed = player.rb.velocity.magnitude;
72+
ArtemisPlayer.Stamina = player.boostCharge;
73+
ArtemisPlayer.Jumping = player.jumping;
74+
ArtemisPlayer.Dead = player.dead;
75+
ArtemisPlayer.CurrentGun = guns.currentSlot;
76+
ArtemisPlayer.CurrentGunVariation = guns.currentVariation;
77+
}
78+
}
79+
80+
public void OnApplicationQuit()
81+
{
82+
ArtemisWebClient?.StopTimer();
83+
}
84+
}
85+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Reflection;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
8+
namespace Artemis.Plugins.Games.Ultrakill.GSI
9+
{
10+
public static class ArtemisPlayer
11+
{
12+
public static float Health;
13+
public static float Speed;
14+
public static float Stamina;
15+
public static bool Jumping;
16+
public static bool Dead;
17+
public static int CurrentGun;
18+
public static int CurrentGunVariation;
19+
20+
public static string ToJson()
21+
{
22+
var b = new StringBuilder();
23+
b.Append('{');
24+
25+
b.AppendTypeAndValue("health", Health);
26+
b.Append(',');
27+
b.AppendTypeAndValue("speed", Speed);
28+
b.Append(',');
29+
b.AppendTypeAndValue("stamina", Stamina);
30+
b.Append(',');
31+
b.AppendTypeAndValue("jumping", Jumping);
32+
b.Append(',');
33+
b.AppendTypeAndValue("dead", Dead);
34+
b.Append(',');
35+
b.AppendTypeAndValue("currentGun", CurrentGun);
36+
b.Append(',');
37+
b.AppendTypeAndValue("currentGunVariation", CurrentGunVariation);
38+
39+
b.Append('}');
40+
41+
return b.ToString();
42+
}
43+
}
44+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
using BepInEx.Logging;
2+
using System;
3+
using System.IO;
4+
using System.Timers;
5+
using UnityEngine;
6+
using UnityEngine.Networking;
7+
using SystemTimer = System.Timers.Timer;
8+
9+
namespace Artemis.Plugins.Games.Ultrakill.GSI
10+
{
11+
public class ArtemisWebClient
12+
{
13+
private const string CONFIG_PATH = @"C:\ProgramData\Artemis\webserver.txt";
14+
private const string PLUGIN_GUID = "ef19ca95-9716-406a-a708-b73c81dbc859";
15+
16+
private readonly SystemTimer timer;
17+
private readonly string _baseUri;
18+
19+
public ArtemisWebClient()
20+
{
21+
if (!File.Exists(CONFIG_PATH))
22+
throw new FileNotFoundException("Artemis: Webserver file not found");
23+
24+
string uri;
25+
try
26+
{
27+
uri = File.ReadAllText(CONFIG_PATH);
28+
}
29+
catch (IOException)
30+
{
31+
Debug.Log("Artemis: Error reading webserver config file");
32+
throw;
33+
}
34+
35+
Debug.Log($"Found artemis web api uri: {uri}");
36+
37+
var request = UnityWebRequest.Get($"{uri}plugins");
38+
try
39+
{
40+
request.SendWithTimeout(TimeSpan.FromMilliseconds(500));
41+
}
42+
catch (Exception e)
43+
{
44+
Debug.Log("Artemis: Failed connecting to webserver");
45+
Debug.Log(e);
46+
47+
throw new Exception("Failed to connect to Artemis, exiting...");
48+
}
49+
50+
_baseUri = $"{uri}plugins/{PLUGIN_GUID}";
51+
52+
Debug.Log("Connected to Artemis, starting timer.");
53+
54+
timer = new SystemTimer(100);
55+
timer.Elapsed += OnTimerElapsed;
56+
}
57+
58+
public void StartTimer() => timer.Start();
59+
public void StopTimer() => timer.Stop();
60+
61+
private void OnTimerElapsed(object sender, ElapsedEventArgs e)
62+
{
63+
Debug.Log("meme");
64+
SendJson("update", ArtemisPlayer.ToJson());
65+
}
66+
67+
private void SendJson(string endpoint, string json)
68+
{
69+
try
70+
{
71+
UnityWebRequest request = UnityWebRequest.Put($"{_baseUri}/{endpoint}", json);
72+
request.method = "POST";
73+
request.SetRequestHeader("Content-Type", "application/json");
74+
request.SendWithTimeout(TimeSpan.FromMilliseconds(100));
75+
}
76+
catch (Exception e)
77+
{
78+
Debug.Log(e);
79+
Debug.Log("Artemis: Stopping timer");
80+
StopTimer();
81+
}
82+
}
83+
84+
public void SendEvent(string endpoint, string args)
85+
{
86+
SendJson(endpoint, args);
87+
}
88+
}
89+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
using System.Collections.Generic;
2+
using System.Globalization;
3+
using System.Linq;
4+
using System.Text;
5+
using UnityEngine;
6+
7+
namespace Artemis.Plugins.Games.Ultrakill.GSI
8+
{
9+
internal static class JsonWriter
10+
{
11+
private static void AppendPropertyName(this StringBuilder b, string name)
12+
{
13+
b.Append('"');
14+
b.Append(name);
15+
b.Append('"');
16+
17+
b.Append(':');
18+
}
19+
20+
private static void AppendTypeAndValueInternal(this StringBuilder b, string name, string value, bool quotes)
21+
{
22+
b.AppendPropertyName(name);
23+
24+
if (quotes)
25+
b.Append('"');
26+
27+
b.Append(value);
28+
29+
if (quotes)
30+
b.Append('"');
31+
}
32+
33+
internal static void AppendTypeAndValue(this StringBuilder b, string name, string value)
34+
=> AppendTypeAndValueInternal(b, name, value, true);
35+
36+
internal static void AppendTypeAndValue(this StringBuilder b, string name, float value)
37+
=> AppendTypeAndValueInternal(b, name, value.ToString(CultureInfo.InvariantCulture), false);
38+
39+
internal static void AppendTypeAndValue(this StringBuilder b, string name, int value)
40+
=> AppendTypeAndValueInternal(b, name, value.ToString(CultureInfo.InvariantCulture), false);
41+
42+
internal static void AppendTypeAndValue(this StringBuilder b, string name, byte value)
43+
=> AppendTypeAndValueInternal(b, name, value.ToString(CultureInfo.InvariantCulture), false);
44+
45+
internal static void AppendTypeAndValue(this StringBuilder b, string name, bool value)
46+
=> AppendTypeAndValueInternal(b, name, value ? "true" : "false", false);
47+
48+
internal static void AppendTypeAndValue(this StringBuilder b, string name, IEnumerable<string> values)
49+
{
50+
b.AppendPropertyName(name);
51+
52+
b.Append('[');
53+
54+
foreach (var item in values)
55+
{
56+
b.Append('"');
57+
b.Append(item);
58+
b.Append('"');
59+
60+
b.Append(',');
61+
}
62+
//remove trailing comma
63+
if (values.Any())
64+
b.Remove(b.Length - 1, 1);
65+
66+
b.Append(']');
67+
}
68+
69+
internal static void AppendTypeAndValue(this StringBuilder b, string name, Color value)
70+
{
71+
b.AppendPropertyName(name);
72+
73+
b.Append("{");
74+
b.AppendTypeAndValue("Red", (byte)(value.r * 255));
75+
b.Append(',');
76+
b.AppendTypeAndValue("Green", (byte)(value.g * 255));
77+
b.Append(',');
78+
b.AppendTypeAndValue("Blue", (byte)(value.b * 255));
79+
b.Append("}");
80+
}
81+
}
82+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using HarmonyLib;
2+
3+
namespace Artemis.Plugins.Games.Ultrakill.GSI.Patches
4+
{
5+
[HarmonyPatch(typeof(HealthBar), "Update")]
6+
public static class Patches
7+
{
8+
public static float MovementSpeed { get; set; }
9+
public static float Health { get; set; }
10+
11+
public static void Postfix(ref float ___hp)
12+
{
13+
Health = ___hp;
14+
}
15+
}
16+
17+
[HarmonyPatch(typeof(NewMovement), "Update")]
18+
public static class PlayerIThink
19+
{
20+
public static void PostFix()
21+
{
22+
23+
}
24+
}
25+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using System;
2+
using UnityEngine.Networking;
3+
4+
namespace Artemis.Plugins.Games.Ultrakill.GSI
5+
{
6+
public static class UnityWebRequestExtensions
7+
{
8+
public static void SendWithTimeout(this UnityWebRequest request, TimeSpan timeout)
9+
{
10+
var startTime = DateTime.UtcNow;
11+
request.SendWebRequest();
12+
while (!request.isDone)
13+
{
14+
if (DateTime.UtcNow > startTime + timeout)
15+
{
16+
throw new TimeoutException();
17+
}
18+
}
19+
}
20+
}
21+
}

0 commit comments

Comments
 (0)