diff --git a/.gitignore b/.gitignore index 8e39a8d..ddbc830 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,8 @@ /_/ /WBM/dll +/scripts/config.sh +/dist +/WBM.zip # Unaltered # Created by https://www.toptal.com/developers/gitignore/api/csharp diff --git a/README.md b/README.md index cbce199..165de25 100644 --- a/README.md +++ b/README.md @@ -50,8 +50,19 @@ Only Windows, MacOS, and Linux are officially supported. It is Not compatible wi ### Installing WBM -1. [Download](https://github.com/War-Brokers-Mods/WBM/releases/latest) the latest version of WBM (a .dll file). -2. Put the dll file in the `/BepInEx/plugins` folder. +1. [Download](https://github.com/War-Brokers-Mods/WBM/releases/latest) the latest version of WBM. (`WBM.zip` file) +2. Unzip it in the `/BepInEx/plugins` folder. + + It should look like this: + + ``` + plugins + └── WBM + ├── assets + │   └── audio + │   └── ... + └── WBM.dll + ``` ### Setting up OBS @@ -172,24 +183,18 @@ If you are a casual user, this is completely unnecessary. **This is only recomme - `Assembly-CSharp-firstpass.dll` - `UnityEngine.*.dll` -4. Run the build command. - - Build in debug mode +4. Create `scripts/config.sh`. ```bash - dotnet build + #!/bin/bash + + WB_PLUGINS_DIR="" ``` - Build in release mode +5. Now you can run the scipts. - ```bash - dotnet build --configuration Release - ``` - -5. The built dll can be found at: - - - `./WBM/bin/Debug/net48/WBM.dll` - - `./WBM/bin/Release/net48/WBM.dll` + - `scripts/debug.sh`: Build WBM in debug mode and copy the files to the plugins directory. + - `scripts/release.sh`: Create a zip file that can be uploaded in the gh release section. ## Bug reports / Suggestions diff --git a/WBM/WBM.cs b/WBM/WBM.cs index fbfbd8f..2800430 100644 --- a/WBM/WBM.cs +++ b/WBM/WBM.cs @@ -1,17 +1,20 @@ using BepInEx; using UnityEngine; +using UnityEngine.Networking; using System; +using System.IO; using System.Collections; +using System.Threading.Tasks; using WebSocketSharp.Server; namespace WBM { - [BepInPlugin("com.developomp.wbm", "War Brokers Mods", "1.1.0.0")] + [BepInPlugin("com.developomp.wbm", "War Brokers Mods", "1.2.0.0")] public partial class WBM : BaseUnityPlugin { - private void Start() + private async void Start() { Logger.LogDebug("WBM: Initializing"); this.webguy = FindObjectOfType(); @@ -28,6 +31,7 @@ namespace WBM this.personGunRef = webguyType.GetField("IEGLIMLBDPH", bindFlags); this.nickListRef = webguyType.GetField("CLLDJOMEKIP", bindFlags); this.gameStateRef = webguyType.GetField("MCGMEPGBCKK", bindFlags); + this.addMessageFuncRef = webguyType.GetMethod("NBPKLIOLLEI", bindFlags); // Load configurations this.showSquadServerRaw = Convert.ToBoolean(PlayerPrefs.GetInt(PrefNames.showSquadServer, 1)); @@ -41,6 +45,43 @@ namespace WBM this.showEloOnLeaderboardRaw = Convert.ToBoolean(PlayerPrefs.GetInt(PrefNames.showElo, 1)); this.data.config.shiftToCrouch = Convert.ToBoolean(PlayerPrefs.GetInt(PrefNames.shiftToCrouch, 1)); + this.killStreakAudioSource = this.gameObject.AddComponent(); + + if (!Directory.Exists(this.audioPath)) + { + Logger.LogError($"Directory {this.audioPath} does not exist. Aborting!"); + GameObject.Destroy(this); + } + + foreach (string fileName in Directory.GetFiles(this.audioPath)) + { + Logger.LogDebug(Path.GetFileNameWithoutExtension(fileName)); + + using (UnityWebRequest uwr = UnityWebRequestMultimedia.GetAudioClip("file://" + Path.Combine(this.audioPath, fileName), AudioType.WAV)) + { + uwr.SendWebRequest(); + + try + { + while (!uwr.isDone) await Task.Delay(5); + + if (uwr.result == UnityWebRequest.Result.ProtocolError) Logger.LogError($"{uwr.error}"); + else + { + this.killStreakAudioDict.Add( + Path.GetFileNameWithoutExtension(fileName), + DownloadHandlerAudioClip.GetContent(uwr) + ); + + } + } + catch (Exception err) + { + Logger.LogError($"{err.Message}, {err.StackTrace}"); + } + } + } + server = new WebSocketServer($"ws://127.0.0.1:{this.serverPort}"); server.AddWebSocketService("/json"); server.Start(); @@ -156,7 +197,7 @@ Reset Everything: (RShift+R)" new Rect(this.GUIOffsetX, this.GUIOffsetY, 220, 60), @"War Brokers Mods Made by [LP] POMP -v1.1.0.0" +v1.2.0.0" ); if (this.data.localPlayerIndex >= 0) @@ -169,7 +210,7 @@ v1.1.0.0" string gamesEloDeltaSign = this.myPlayerStats.gamesEloDelta >= 0 ? "+" : ""; GUI.Box( - new Rect(this.GUIOffsetX, this.GUIOffsetY + 65, 220, 160), + new Rect(this.GUIOffsetX, this.GUIOffsetY + 65, 220, 180), $@"Player stats KDR: {Util.formatKDR(this.myPlayerStats.kills, this.myPlayerStats.deaths)} @@ -178,12 +219,13 @@ games Elo: {this.myPlayerStats.gamesElo} {gamesEloDeltaSign}{this.myPlayerStats. Damage dealt: {this.myPlayerStats.damage} Longest Kill: {this.myPlayerStats.longestKill}m Points: {this.myPlayerStats.points} -HeadShots: {this.myPlayerStats.headShots}" +Headshots: {this.myPlayerStats.headShots} +Kill streak: {this.killStreak}" ); } catch (Exception e) { - Logger.LogDebug(e); + Logger.LogError(e); } } @@ -192,7 +234,7 @@ HeadShots: {this.myPlayerStats.headShots}" try { GUI.Box( - new Rect(this.GUIOffsetX, this.GUIOffsetY + 230, 230, 130), + new Rect(this.GUIOffsetX, this.GUIOffsetY + 250, 230, 130), $@"Weapon stats fire Timer: {String.Format("{0:0.00}", Util.getGunFireTimer(this.personGun))}s (max: {String.Format("{0:0.00}", Util.getGunFireRate(this.personGun))}s) @@ -204,7 +246,7 @@ zoom: {Util.getGunZoom(this.personGun)}" } catch (Exception e) { - Logger.LogDebug(e); + Logger.LogError(e); } } @@ -255,7 +297,7 @@ total kills: {teamTotalKills}" } catch (Exception e) { - Logger.LogDebug(e); + Logger.LogError(e); } } } @@ -276,6 +318,34 @@ total kills: {teamTotalKills}" this.personGun = this.personGunRaw; this.data.nickList = this.nickListRaw; this.data.gameState = this.gameStateRaw; + + // check if deaths has changed since the last value update + if (this.prevDeaths == this.myPlayerStats.deaths) + { + this.killStreak = this.myPlayerStats.kills - this.killCountBeforeDeath; + + if (this.prevKills != this.myPlayerStats.kills) + { + Logger.LogDebug(this.killStreakAudioDict); + + if (this.killStreakSFXDictionary.ContainsKey(this.killStreak)) + { + this.killStreakAudioSource.clip = this.killStreakAudioDict[this.killStreakSFXDictionary[this.killStreak]]; + this.killStreakAudioSource.Play(); + + this.addMessageFuncRef.Invoke(this.webguy, new object[] { $"You are on a {this.killStreak} kill streak", -1 }); + } + } + } + else + { + // reset kill streak when death count changes + + this.killCountBeforeDeath = this.myPlayerStats.kills; + this.prevDeaths = this.myPlayerStats.deaths; + this.killStreak = 0; + } + this.prevKills = this.myPlayerStats.kills; } this.data.config.showSquadServer = this.showSquadServerRaw; @@ -286,7 +356,7 @@ total kills: {teamTotalKills}" } catch (Exception e) { - Logger.LogDebug(e); + Logger.LogError(e); } yield return new WaitForSeconds(0.1f); diff --git a/WBM/WBMVariable.cs b/WBM/WBMVariable.cs index bcd61f6..d8dba69 100644 --- a/WBM/WBMVariable.cs +++ b/WBM/WBMVariable.cs @@ -1,5 +1,9 @@ +using UnityEngine; + +using System.IO; using System.Reflection; using System.Collections; +using System.Collections.Generic; using WebSocketSharp.Server; @@ -21,6 +25,17 @@ namespace WBM private int GUIOffsetY; private int DefaultGUIOffsetY = 325; + private Dictionary killStreakAudioDict = new Dictionary(); + private string audioPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "assets/audio"); + private AudioSource killStreakAudioSource; + private Dictionary killStreakSFXDictionary = new Dictionary() + { + {10, "rampage"}, + {20,"killing spree"}, + {30, "unstoppable"}, + {50, "godlike"} + }; + private FieldInfo showEloOnLeaderboardRef; private bool showEloOnLeaderboardRaw { @@ -93,6 +108,10 @@ namespace WBM } } private Data.PlayerStatsStruct myPlayerStats; + private int prevDeaths = 0; + private int prevKills = 0; + private int killCountBeforeDeath = 0; + private int killStreak = 0; private FieldInfo currentAreaRef; private int currentAreaRaw @@ -150,5 +169,7 @@ namespace WBM return (Data.GameStateEnum)gameStateRef.GetValue(this.webguy); } } + + private MethodInfo addMessageFuncRef; } } diff --git a/assets/audio/godlike.wav b/assets/audio/godlike.wav new file mode 100644 index 0000000..70f6c0f Binary files /dev/null and b/assets/audio/godlike.wav differ diff --git a/assets/audio/killingspree.wav b/assets/audio/killingspree.wav new file mode 100644 index 0000000..14b6ef1 Binary files /dev/null and b/assets/audio/killingspree.wav differ diff --git a/assets/audio/multikill.wav b/assets/audio/multikill.wav new file mode 100644 index 0000000..80cd2e9 Binary files /dev/null and b/assets/audio/multikill.wav differ diff --git a/assets/audio/rampage.wav b/assets/audio/rampage.wav new file mode 100644 index 0000000..53ed625 Binary files /dev/null and b/assets/audio/rampage.wav differ diff --git a/assets/audio/unstoppable.wav b/assets/audio/unstoppable.wav new file mode 100644 index 0000000..3c2a0a9 Binary files /dev/null and b/assets/audio/unstoppable.wav differ diff --git a/scripts/debug.sh b/scripts/debug.sh new file mode 100755 index 0000000..99a5c00 --- /dev/null +++ b/scripts/debug.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" + +cd "$SCRIPT_DIR" || { + echo "Can not locate script directory" + exit +} +cd .. +source ./scripts/config.sh + +dotnet build +rm "$WB_PLUGINS_DIR/WBM/WBM.dll" +mkdir -p "$WB_PLUGINS_DIR/WBM" +cp ./WBM/bin/Debug/net48/WBM.dll "$WB_PLUGINS_DIR/WBM/WBM.dll" +cp -R ./assets "$WB_PLUGINS_DIR/WBM" diff --git a/scripts/release.sh b/scripts/release.sh new file mode 100755 index 0000000..3acbae7 --- /dev/null +++ b/scripts/release.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" + +cd "$SCRIPT_DIR" || { + echo "Can not locate script directory" + exit +} +cd .. +source ./scripts/config.sh + +dotnet build --configuration Release +[ -e ./dist ] && rm -rf ./dist +mkdir ./dist +cp ./WBM/bin/Release/net48/WBM.dll ./dist/WBM.dll +cp -R ./assets ./dist/assets + +[ -e ./WBM.zip ] && rm ./WBM.zip +cd ./dist +zip -r WBM.zip ./* +mv ./WBM.zip .. +cd .. +rm -rf ./dist