From a16eb79973e571ae3e1711b88aba81d6eac21d64 Mon Sep 17 00:00:00 2001 From: Daemon Date: Wed, 14 Apr 2021 12:37:47 +0100 Subject: [PATCH 1/2] Updated version and README --- README.md | 3 ++- Unify/Unify.cs | 2 +- Unify/Unify.csproj | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 472b8a0..b5ba8b8 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,8 @@ Other mods can add regions via the > If you are still using 2021.3.5s and Reactor fails to load, try using the Reactor version located > here: https://github.com/NuclearPowered/Reactor/actions/runs/636023321. -1. Ensure that BepInEx and Reactor are installed ([installation guide](INSTALLATION.md)). +1. Ensure that BepInEx and Reactor (Reactor is not required for pre releases) are installed + ([installation guide](INSTALLATION.md)). 2. Download the latest mod on the [releases](https://github.com/DaemonBeast/Unify/releases) page for the version of Among Us you are using. 3. Move the mod to the `(Among Us game files)/BepInEx/plugins` folder. diff --git a/Unify/Unify.cs b/Unify/Unify.cs index 63af2e7..7be037c 100644 --- a/Unify/Unify.cs +++ b/Unify/Unify.cs @@ -20,7 +20,7 @@ namespace Unify { public const string Id = "daemon.unify"; private const string Name = "Unify"; - private const string Version = "4.0.0"; + private const string Version = "4.0.1"; public static ConfigFile ConfigFile { get; private set; } diff --git a/Unify/Unify.csproj b/Unify/Unify.csproj index 47e2a6b..5806e21 100644 --- a/Unify/Unify.csproj +++ b/Unify/Unify.csproj @@ -1,7 +1,7 @@ netstandard2.1 - 4.0.0 + 4.0.1 NuclearPowered/Mappings:0.4.0 Region mod From 9c70216a9f8d1c0aa6f6a2591ecffc89bfe59cf7 Mon Sep 17 00:00:00 2001 From: Daemon Date: Wed, 21 Apr 2021 22:26:53 +0100 Subject: [PATCH 2/2] Tidied code and fixed bugs Tidied code and removed redundant code Fixed region file getting spam reloaded Fixed multiple direct connect buttons existing at once Added IP and port under names of custom regions in regions menu --- .idea/.idea.Unify/.idea/indexLayout.xml | 2 +- README.md | 2 +- Unify/Patches/Regions.cs | 135 +++++++++--------------- Unify/Unify.cs | 6 +- Unify/Unify.csproj | 4 +- build/Unify-2021.4.12s.dll | Bin 11776 -> 11264 bytes 6 files changed, 58 insertions(+), 91 deletions(-) diff --git a/.idea/.idea.Unify/.idea/indexLayout.xml b/.idea/.idea.Unify/.idea/indexLayout.xml index 27ba142..7b08163 100644 --- a/.idea/.idea.Unify/.idea/indexLayout.xml +++ b/.idea/.idea.Unify/.idea/indexLayout.xml @@ -1,6 +1,6 @@ - + diff --git a/README.md b/README.md index b5ba8b8..e7aace3 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ Custom regions can be added as detailed below in the [configuration](#configuration) section. Other mods can add regions via the -`AddRegion(string name, string ip)` method. +`AddRegion(string name, string ip, ushort port)` method. ## Installation diff --git a/Unify/Patches/Regions.cs b/Unify/Patches/Regions.cs index 44652a7..9e00e02 100644 --- a/Unify/Patches/Regions.cs +++ b/Unify/Patches/Regions.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using BepInEx.Configuration; using HarmonyLib; +using Reactor.Extensions; using UnityEngine; using UnityEngine.UI; using Object = UnityEngine.Object; @@ -12,7 +13,7 @@ namespace Unify.Patches public static class RegionsPatch { private static IRegionInfo[] _oldRegions { get; } = ServerManager.DefaultRegions; - + private static IRegionInfo[] _newRegions { get; } = new IRegionInfo[] { new DnsRegionInfo("192.241.154.115", "skeld.net", StringNames.NoTranslation, "192.241.154.115", 22023) @@ -32,7 +33,7 @@ namespace Unify.Patches public static void Patch() { ServerManager serverManager = ServerManager.Instance; - + IRegionInfo[] patchedRegions = _oldRegions .AddRangeToArray(_newRegions) .AddRangeToArray(ModRegions.ToArray()) @@ -41,13 +42,12 @@ namespace Unify.Patches ServerManager.DefaultRegions = patchedRegions; serverManager.AvailableRegions = patchedRegions; - serverManager.SaveServers(); } private static IRegionInfo[] LoadCustomUserRegions() { List customRegions = new List(); - + for (int x = 0; x < 9; x++) { ConfigEntry regionName = UnifyPlugin.ConfigFile.Bind( @@ -60,19 +60,20 @@ namespace Unify.Patches if (String.IsNullOrWhiteSpace(regionIp.Value)) continue; IRegionInfo regionInfo = new DnsRegionInfo( - regionIp.Value, regionName.Value, StringNames.NoTranslation, regionIp.Value, regionPort.Value) + regionIp.Value, $"{regionName.Value}\n{regionIp.Value} {regionPort.Value}", + StringNames.NoTranslation, regionIp.Value, regionPort.Value) .Cast(); - + customRegions.Add(regionInfo); } return customRegions.ToArray(); } - + private static void UpdateRegion() { - RegionMenu regionMenu = GameObject.Find("RegionMenu").GetComponent(); - + RegionMenu regionMenu = DestroyableSingleton.Instance; + bool success = UnifyPlugin.SetDirectRegion(DirectConnect.text, out IRegionInfo newRegion); if (!success) @@ -80,84 +81,22 @@ namespace Unify.Patches DirectConnect.StartCoroutine(Effects.SwayX(DirectConnect.transform, 0.75f, 0.25f)); return; } - + regionMenu.ChooseOption(newRegion); regionMenu.Close(); } [HarmonyPatch(typeof(ServerManager), nameof(ServerManager.LoadServers))] - public static class PatchRegionMenuPatch + public static class LoadNewRegionsPatch { public static void Postfix() { Patch(); } } - - [HarmonyPatch(typeof(RegionMenu), nameof(RegionMenu.Open))] - public static class DirectConnectButtonPatch - { - public static void Postfix() - { - JoinGameButton joinGameButton = DestroyableSingleton.Instance; - RegionMenu regionMenu = DestroyableSingleton.Instance; - - DirectConnect = Object.Instantiate(joinGameButton.GameIdText, regionMenu.transform); - DirectConnect.gameObject.SetActive(false); - DirectConnect.IpMode = true; - DirectConnect.characterLimit = 15; - DirectConnect.ClearOnFocus = false; - - DirectConnect.OnEnter = new Button.ButtonClickedEvent(); - DirectConnect.OnEnter.AddListener((Action) UpdateRegion); - - int offset = _newRegions.Length + ModRegions.Count; - DirectConnect.transform.localPosition = new Vector3(0, 1f - (offset / 2f), -100f); - } - } - - [HarmonyPatch(typeof(RegionMenu), nameof(RegionMenu.Open))] - public static class RegionMenuLayoutPatch - { - public static void Postfix(RegionMenu __instance) - { - DirectConnect.gameObject.SetActive(true); - - var regionButtons = __instance.ButtonPool.activeChildren.ToArray(); - - for (int i = 0; i < regionButtons.Length; i++) - { - ServerListButton regionButton = regionButtons[i].Cast(); - - (float x, float y) = CalculatePosition(i); - regionButton.transform.localPosition = new Vector3(1.25f + x, 2f - 0.5f * y, 0f); - } - } - - private static (float x, float y) CalculatePosition(int index) - { - // currently broken - /*if (DirectRegion != null && ServerManager.DefaultRegions[index].Name == DirectRegion.Name) - { - int offset = Math.Max( - Math.Max(LoadCustomUserRegions().Length, _newRegions.Length + ModRegions.Count), - _oldRegions.Length); - return (1.25f, 2f - offset); - }*/ - - bool isCustomRegion = index >= _oldRegions.Length; - bool isCustomUserRegion = index >= _oldRegions.Length + _newRegions.Length + ModRegions.Count; - float x = (isCustomRegion ? 3f : 0) + (isCustomUserRegion ? 3f : 0) - 4.25f; - float y = index - (isCustomRegion ? _oldRegions.Length : 0) - - (isCustomUserRegion ? _newRegions.Length + ModRegions.Count : 0); - - return (x, y); - } - } [HarmonyPatch(typeof(JoinGameButton), nameof(JoinGameButton.OnClick))] - public static class DirectConnectEnterButtonPatch - { + public static class DirectConnectEnterButtonPatch { public static bool Prefix(JoinGameButton __instance) { GameObject regionMenuGameObject = GameObject.Find("RegionMenu"); @@ -169,21 +108,47 @@ namespace Unify.Patches } } - [HarmonyPatch(typeof(RegionMenu), nameof(RegionMenu.Close))] - public static class HideDirectConnectPatch + [HarmonyPatch(typeof(RegionMenu))] + public static class RegionMenuPatches { - public static void Postfix() + [HarmonyPatch(nameof(RegionMenu.Open))] + [HarmonyPostfix] + public static void DirectConnectButtonPatch(RegionMenu __instance) { - DirectConnect.gameObject.SetActive(false); - } - } + if (DirectConnect) DirectConnect.gameObject.Destroy(); - [HarmonyPatch(typeof(RegionMenu), nameof(RegionMenu.ChooseOption))] - public static class HideDirectConnectOnSelectPatch - { - public static void Postfix() + JoinGameButton joinGameButton = DestroyableSingleton.Instance; + + DirectConnect = Object.Instantiate(joinGameButton.GameIdText, __instance.transform); + DirectConnect.IpMode = true; + DirectConnect.characterLimit = 15; + DirectConnect.ClearOnFocus = false; + + DirectConnect.OnEnter = new Button.ButtonClickedEvent(); + DirectConnect.OnEnter.AddListener((Action) UpdateRegion); + + int offset = _newRegions.Length + ModRegions.Count; + DirectConnect.transform.localPosition = new Vector3(0, 1f - (offset / 2f), -100f); + } + + [HarmonyPatch(nameof(RegionMenu.Open))] + [HarmonyPostfix] + public static void RegionMenuLayoutPatch(RegionMenu __instance) { - DirectConnect.gameObject.SetActive(false); + var regionButtons = __instance.ButtonPool.activeChildren.ToArray(); + + for (int i = 0; i < regionButtons.Length; i++) + { + ServerListButton regionButton = regionButtons[i].Cast(); + + bool isCustomRegion = i >= _oldRegions.Length; + bool isCustomUserRegion = i >= _oldRegions.Length + _newRegions.Length + ModRegions.Count; + float x = (isCustomRegion ? 3f : 0) + (isCustomUserRegion ? 3f : 0) - 4.25f; + float y = i - (isCustomRegion ? _oldRegions.Length : 0) - + (isCustomUserRegion ? _newRegions.Length + ModRegions.Count : 0); + + regionButton.transform.localPosition = new Vector3(1.25f + x, 2f - 0.5f * y, 0f); + } } } } diff --git a/Unify/Unify.cs b/Unify/Unify.cs index 7be037c..c779dbe 100644 --- a/Unify/Unify.cs +++ b/Unify/Unify.cs @@ -20,7 +20,7 @@ namespace Unify { public const string Id = "daemon.unify"; private const string Name = "Unify"; - private const string Version = "4.0.1"; + private const string Version = "4.1.0"; public static ConfigFile ConfigFile { get; private set; } @@ -48,7 +48,7 @@ namespace Unify Harmony.PatchAll(); } - public static IRegionInfo AddRegion(string name, string ip) + public static IRegionInfo AddRegion(string name, string ip, ushort port) { if (Uri.CheckHostName(ip) != UriHostNameType.IPv4) return ServerManager.Instance.CurrentRegion; @@ -56,7 +56,7 @@ namespace Unify ServerManager.DefaultRegions.ToArray().FirstOrDefault(region => region.PingServer == ip); if (existingRegion != null) return existingRegion; - IRegionInfo newRegion = new DnsRegionInfo(ip, name, StringNames.NoTranslation, ip, 22023) + IRegionInfo newRegion = new DnsRegionInfo(ip, $"{name}\n{ip} {port}", StringNames.NoTranslation, ip, port) .Cast(); RegionsPatch.ModRegions.Add(newRegion); diff --git a/Unify/Unify.csproj b/Unify/Unify.csproj index 5806e21..42eee82 100644 --- a/Unify/Unify.csproj +++ b/Unify/Unify.csproj @@ -1,7 +1,7 @@ netstandard2.1 - 4.0.1 + 4.1.0 NuclearPowered/Mappings:0.4.0 Region mod @@ -32,5 +32,7 @@ + + \ No newline at end of file diff --git a/build/Unify-2021.4.12s.dll b/build/Unify-2021.4.12s.dll index 3319bc5af6a276c523efc63b2f0b54c7febc6210..08d20f72134ddd636987862167e47c5bb5af58fa 100644 GIT binary patch delta 4503 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 U5A0cdia*|er>Eo;Yb!JU2NQn{hyVZp delta 4798 zcmZ`-3vg7`8UD|?ckjJ>cUiIsKBUwo#>_Q&M zqq0j242W8HE=I*#H9kf}rlzqKT3>*pD5XPVoPnMwDj-_-Lz<6`3tTi2S%mT6eKx7P5ZBir8rDZ>+#q2@B$yj+>K>o`H|) z`9#d>3r@1?_;YNXb&=1DbN^Wd&ey@c>euHJb!HNoA;^lIA$Zh`Se6jD1sVQO88U}= zY$aL|@d&3G(nc&|WJx8evxiCnM%nmp4j=dPxnT=t0+Te_bazN&U^Lc0(i0}C}OKo%v*{VeD z&LYT6uVeB{5QG@Q=r{uJdiH|5N1+Cx5MFnjfu!RLz>pZSN4h_tH<&>$3*b*F4*DU* zY%AB6*H&haAsW+=D65+ixYgKb$gk8l)26v?vbu=Np%1rLO!@ZPZ?#weTH(x6l`tEa zIdXRd;5;-2;+TOz&Cp;Z6uZjmvt`H8J!Sz>Wd$H{U1+RODg%rRYkF)P2rV`qDC=X; z1F$GAVZjVd03>u&%y$oFiUqwLlSHaFiBv^bNcMZv+8fO7SSGXt_|HxdYH>jh?490V zPKPDb`lOoB5^P$_TC4f5OU>9mM1$(PLz6^AlL2O|9H_-aW+6NB4P}Tnk~v=knKw2C zXnn0Mi91r#bPb3^4J!0ycu?iSMm!Gg@4Oz$F{}bn0@)*L@kG+@D;Be*MINgasy7I@ z5rFn7z7a*7Ap|Dk&_%~;!F4ksaITw0)L;&hQNqz<6~+STRzQXQX5k!b>Hp5<3~Mp0 zX|wD(ITc4R7n~>Lkk;hljn%;6g2rV|qq7cF`1UKU6sm_{49^aSu;4XsxaLYdyfLpR@j#I* z`W;5_x-T&&h3m03!Rre6DxBNZ(H33WDH8r8_KMfBj0zj((snF$%p4V7-%yKPi=G7k zq-Ooq7#T7vn|GrHX$rcQ59@ja+;)`cn_;I=sPl^YE8(9JoJ!eXC|HC zrMgBBC~q5Hn(qihQfNPKYE+JwG3-{QUiZ>8 zCCqZ^J+y~LWtw<99-6s?d8Aw_L|g?Fp&X{s4xVjjR75v`?jfP`DMsazj_MT9az*Gg z$+wDQr`<&6=S`D7LqI0Q$2rcM>nIbdF8Y8IeM&w(EHSG2lrs7kEQD!`anPPmI}PzRtoW1y znh-|@UQ#rX>#q@YJ{NviEg4B^`%-q)#w*6c#kRYdGaZ_)Pfr1Qa3P+ z{HDRe>#|ypARvULzKt|?NxUfWu=1jj%|3y?MqeotY#N>^pZA|af$~BR}Y=nLQJK-lG~iK-Ka$n?+oCMOYWzXO;4j4Kb2h47-iodXF7e6 zW;fdRgS#NP9;4iT5FC>`Pmgg#dk376=1ysU0hb}Uq)}s@U?FN`cX2!YImPDm8bb9BeA7iv84kfE25@!3%kS2!b~+}xBz5SP zYEm0M{bHQmu}5{%#xy6a4Ei1?dMJp=WaLyRj-smQNCxDfv(ajd0uob7DO|&ad2uni zh*iO84fl~K^(e~GmSMi#N{q^Bkl77va;yd3r))rHY&SMjExpL^23BzkU6P?a1e~JP z(i)0i;=9nB?R*akV$)v+Hre;n<5cW8L_;w6H0Z77S=tNw61_!-O@rmpa+bx8(|lV2 z3qW3qqKZ&X0xQ@VDft|@iZQm`xSzR!wX~8Nj9%trOB@Ak6f1O`gPr2I9k+Nhdl10| z*h#aOwXxOOV|)$UM^E#uEU5JHM%JVM7Pwxir77@rkUx&F;^+7@nf(ljJK3MiE~Src zRMskOY?8T6X=cT?q!M61;{sQiJ-{JmQrRbS3b0z^VMwkudX={zIZf}d+s$W`<7}+a zr{vKAbB}To@|TpAY@>caX=Jmt3F_x;vv!R-4>g`0R~J!}cB|S#chM@~v$PhHB5jY- zg1on>Zob|4h1v(BeX0*M+ygP|K$lhyEM-$A)=Hcsu~A~P#5Rd5CAvt(M()BkbrsM_ zS5w4~FW*cmp@;d0wi0@Rp9AjVSy~D8^L*g%cmwbNZw4OXQQ#529{4Wb2K<2c0M7y| zrJX7|L^Z66j!+BmUAhza0sY*%ICyAHKl?X7K>h4(<)qa8K+=o}{|f78ui|Vi=t9ti zwn|A)l~@JI2HP~YjX$YcH5uWlw^1*hVOR5Qe6dobZc;hcgDOASC-?+L_~c#<9AiI< zRkKCnwf1*Gf2ExQE;7$pZ)Qx5yO@iw<{SBIyhUkOYSczGs;UWjY8MMFeO2LPAnaeh z7|oPx5hq1lp0v0@oELDZsfWZJSl8lPBd*JOc4-J}p0M;UU$x@!f$*{2rPXoXkb?)x zK9Y`w6LI=TT{+U=K)s35=Rlb#%RnE+M8~C#fr=@|-_66MYpkn0SrZL7w&ON&2k`qQ zhvV1JnM!Uw9QB8Mr$t`6xzq!3T zGOv3@djw1^-a`~w(iQ6%*FPxpxZ;+ts@o&WBhju|&C4U5)(P)6J<>IGNmtt{t0nu^ z*80fOwpg^YuDNSTD@|`}iA-zjfQ719G>XUU=-fy27cCiqyqA+xl9EcZ z-K|_7>9TtB%Bns zjbaqV5{Ll1tylB!bbLMAFP)JRhZm5otLoE%&J?DHmX908iqi6rVIi3}-xv(<$j0R1XRYb2^+SzFpkEn{PvsXl-_z|It#1F&DdBf?HM!z=wC~o4SlwBt5Qg#^AD#|GJ zF-zb?kQK+6NIJJ44WU(4RbjeHa5)B zYPLpfQ<(L{@zmp}b+({|Ew+3k8tk^J_E;ynrA2UqoK>wcu(MZmVeMJb5v9y$Jvt)h zLW_weGa1>&my}w0!8~hX(B*X&5sj~wyNrZcg7zl^US3&ktqMM9y%wyrTqD=w=ZBio i>Q9bb$k5=Q75xWzIy4UG8+DG~GNIocKF5-!`u_m&2t>aC