Skip to content

Commit

Permalink
Add ultrakill
Browse files Browse the repository at this point in the history
  • Loading branch information
diogotr7 committed Jun 16, 2023
1 parent 45d8223 commit 494b7f3
Show file tree
Hide file tree
Showing 13 changed files with 510 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net472</TargetFramework>
<DebugType>Full</DebugType>
<LangVersion>latest</LangVersion>
</PropertyGroup>


<PropertyGroup>
<SteamLibraryPath>C:\Program Files (x86)\Steam\steamapps\common</SteamLibraryPath>
</PropertyGroup>

<ItemGroup>
<Reference Include="Assembly-CSharp">
<HintPath>$(SteamLibraryPath)\ULTRAKILL\ULTRAKILL_Data\Managed\Assembly-CSharp.dll</HintPath>
<PrivateAssets>all</PrivateAssets>
</Reference>
</ItemGroup>

<ItemGroup>
<PackageReference Include="BepInEx.BaseLib" Version="5.4.21" />
<PackageReference Include="UnityEngine" Version="5.6.1" />
<PackageReference Include="UnityEngine.Modules" Version="2022.1.16" />
<PackageReference Include="HarmonyX" Version="2.10.1" />

<PackageReference Update="@(PackageReference)" IncludeAssets="compile;build" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
using Artemis.Plugins.Games.Ultrakill.GSI.Patches;
using BepInEx;
using HarmonyLib;
using System;
using System.Linq;
using UnityEngine;
using UnityEngine.SceneManagement;

namespace Artemis.Plugins.Games.Ultrakill.GSI
{
[BepInPlugin("com.artemis.gsi", "Artemis GSI", "0.1")]
public class ArtemisGsiPlugin : BaseUnityPlugin
{
public static ArtemisWebClient ArtemisWebClient => _artemisWebClient;
private static ArtemisWebClient _artemisWebClient;

private NewMovement player = null;
private GunControl guns = null;

public void Awake()
{
try
{
_artemisWebClient = new ArtemisWebClient();
}
catch (Exception e)
{
Debug.Log(e);
return;
}
//Harmony harmony = new Harmony("com.artemis.gsi");
// harmony.PatchAll();

Debug.Log("patched artemis");
ArtemisWebClient.StartTimer();
}

public void Start()
{
SceneManager.activeSceneChanged += OnSceneChanged;
}

private void OnSceneChanged(Scene from, Scene to)
{
Debug.Log($"Scene changed to {to.name}");
player = null;
if (SceneManager.GetActiveScene().name.StartsWith("Level") || SceneManager.GetActiveScene().name == "uk_construct")
{
player = FindObjectOfType<NewMovement>();
Debug.Log($"Found player! name:{player.gameObject.name}");
}
if (guns == null)
{
guns = MonoSingleton<GunControl>.Instance;
}
}

public void Update()
{
if (player != null)
{
//Debug.Log($"Health: {player.hp}");
//Debug.Log($"Speed: {player.rb.velocity.magnitude}");
//Debug.Log($"Stamina: {player.boostCharge}");
//Debug.Log($"Jumping: {player.jumping}");
//Debug.Log($"Dead: {player.dead}");
//Debug.Log($"Gun slot: {guns.currentSlot}");
//Debug.Log($"variation: {guns.currentVariation}");

ArtemisPlayer.Health = player.hp;
ArtemisPlayer.Speed = player.rb.velocity.magnitude;
ArtemisPlayer.Stamina = player.boostCharge;
ArtemisPlayer.Jumping = player.jumping;
ArtemisPlayer.Dead = player.dead;
ArtemisPlayer.CurrentGun = guns.currentSlot;
ArtemisPlayer.CurrentGunVariation = guns.currentVariation;
}
}

public void OnApplicationQuit()
{
ArtemisWebClient?.StopTimer();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace Artemis.Plugins.Games.Ultrakill.GSI
{
public static class ArtemisPlayer
{
public static float Health;
public static float Speed;
public static float Stamina;
public static bool Jumping;
public static bool Dead;
public static int CurrentGun;
public static int CurrentGunVariation;

public static string ToJson()
{
var b = new StringBuilder();
b.Append('{');

b.AppendTypeAndValue("health", Health);
b.Append(',');
b.AppendTypeAndValue("speed", Speed);
b.Append(',');
b.AppendTypeAndValue("stamina", Stamina);
b.Append(',');
b.AppendTypeAndValue("jumping", Jumping);
b.Append(',');
b.AppendTypeAndValue("dead", Dead);
b.Append(',');
b.AppendTypeAndValue("currentGun", CurrentGun);
b.Append(',');
b.AppendTypeAndValue("currentGunVariation", CurrentGunVariation);

b.Append('}');

return b.ToString();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
using BepInEx.Logging;
using System;
using System.IO;
using System.Timers;
using UnityEngine;
using UnityEngine.Networking;
using SystemTimer = System.Timers.Timer;

namespace Artemis.Plugins.Games.Ultrakill.GSI
{
public class ArtemisWebClient
{
private const string CONFIG_PATH = @"C:\ProgramData\Artemis\webserver.txt";
private const string PLUGIN_GUID = "ef19ca95-9716-406a-a708-b73c81dbc859";

private readonly SystemTimer timer;
private readonly string _baseUri;

public ArtemisWebClient()
{
if (!File.Exists(CONFIG_PATH))
throw new FileNotFoundException("Artemis: Webserver file not found");

string uri;
try
{
uri = File.ReadAllText(CONFIG_PATH);
}
catch (IOException)
{
Debug.Log("Artemis: Error reading webserver config file");
throw;
}

Debug.Log($"Found artemis web api uri: {uri}");

var request = UnityWebRequest.Get($"{uri}plugins");
try
{
request.SendWithTimeout(TimeSpan.FromMilliseconds(500));
}
catch (Exception e)
{
Debug.Log("Artemis: Failed connecting to webserver");
Debug.Log(e);

throw new Exception("Failed to connect to Artemis, exiting...");
}

_baseUri = $"{uri}plugins/{PLUGIN_GUID}";

Debug.Log("Connected to Artemis, starting timer.");

timer = new SystemTimer(100);
timer.Elapsed += OnTimerElapsed;
}

public void StartTimer() => timer.Start();
public void StopTimer() => timer.Stop();

private void OnTimerElapsed(object sender, ElapsedEventArgs e)
{
Debug.Log("meme");
SendJson("update", ArtemisPlayer.ToJson());
}

private void SendJson(string endpoint, string json)
{
try
{
UnityWebRequest request = UnityWebRequest.Put($"{_baseUri}/{endpoint}", json);
request.method = "POST";
request.SetRequestHeader("Content-Type", "application/json");
request.SendWithTimeout(TimeSpan.FromMilliseconds(100));
}
catch (Exception e)
{
Debug.Log(e);
Debug.Log("Artemis: Stopping timer");
StopTimer();
}
}

public void SendEvent(string endpoint, string args)
{
SendJson(endpoint, args);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using UnityEngine;

namespace Artemis.Plugins.Games.Ultrakill.GSI
{
internal static class JsonWriter
{
private static void AppendPropertyName(this StringBuilder b, string name)
{
b.Append('"');
b.Append(name);
b.Append('"');

b.Append(':');
}

private static void AppendTypeAndValueInternal(this StringBuilder b, string name, string value, bool quotes)
{
b.AppendPropertyName(name);

if (quotes)
b.Append('"');

b.Append(value);

if (quotes)
b.Append('"');
}

internal static void AppendTypeAndValue(this StringBuilder b, string name, string value)
=> AppendTypeAndValueInternal(b, name, value, true);

internal static void AppendTypeAndValue(this StringBuilder b, string name, float value)
=> AppendTypeAndValueInternal(b, name, value.ToString(CultureInfo.InvariantCulture), false);

internal static void AppendTypeAndValue(this StringBuilder b, string name, int value)
=> AppendTypeAndValueInternal(b, name, value.ToString(CultureInfo.InvariantCulture), false);

internal static void AppendTypeAndValue(this StringBuilder b, string name, byte value)
=> AppendTypeAndValueInternal(b, name, value.ToString(CultureInfo.InvariantCulture), false);

internal static void AppendTypeAndValue(this StringBuilder b, string name, bool value)
=> AppendTypeAndValueInternal(b, name, value ? "true" : "false", false);

internal static void AppendTypeAndValue(this StringBuilder b, string name, IEnumerable<string> values)
{
b.AppendPropertyName(name);

b.Append('[');

foreach (var item in values)
{
b.Append('"');
b.Append(item);
b.Append('"');

b.Append(',');
}
//remove trailing comma
if (values.Any())
b.Remove(b.Length - 1, 1);

b.Append(']');
}

internal static void AppendTypeAndValue(this StringBuilder b, string name, Color value)
{
b.AppendPropertyName(name);

b.Append("{");
b.AppendTypeAndValue("Red", (byte)(value.r * 255));
b.Append(',');
b.AppendTypeAndValue("Green", (byte)(value.g * 255));
b.Append(',');
b.AppendTypeAndValue("Blue", (byte)(value.b * 255));
b.Append("}");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using HarmonyLib;

namespace Artemis.Plugins.Games.Ultrakill.GSI.Patches
{
[HarmonyPatch(typeof(HealthBar), "Update")]
public static class Patches
{
public static float MovementSpeed { get; set; }
public static float Health { get; set; }

public static void Postfix(ref float ___hp)
{
Health = ___hp;
}
}

[HarmonyPatch(typeof(NewMovement), "Update")]
public static class PlayerIThink
{
public static void PostFix()
{

}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System;
using UnityEngine.Networking;

namespace Artemis.Plugins.Games.Ultrakill.GSI
{
public static class UnityWebRequestExtensions
{
public static void SendWithTimeout(this UnityWebRequest request, TimeSpan timeout)
{
var startTime = DateTime.UtcNow;
request.SendWebRequest();
while (!request.isDone)
{
if (DateTime.UtcNow > startTime + timeout)
{
throw new TimeoutException();
}
}
}
}
}
Loading

0 comments on commit 494b7f3

Please sign in to comment.