private void Run_Update(On.RoR2.Run.orig_Update orig, RoR2.Run self) { orig.Invoke(self); //Wait till all players loaded //Dont know if there is a better option for this if (RoR2.Run.instance.time < 5) { return; } //Compare this user with the host user bool isHost = LocalUserManager.GetFirstLocalUser().cachedMasterController == PlayerCharacterMasterController.instances[0]; //If Not host unhook the update function and quit this function if (!isHost) { On.RoR2.Run.Update -= Run_Update; return; } //If Host send a Reset, so everything is setup correctly ExampleCommandClientCustom.Invoke(x => { x.Write("Reset"); //Send this to every client so its host dependend x.Write(config.Everything_Avaiable); }); //Hook host specific stuff On.EntityStates.Barrel.Opening.OnEnter += Opening_OnEnter; On.RoR2.PurchaseInteraction.OnInteractionBegin += PurchaseInteraction_OnInteractionBegin; //Unhook the Update function On.RoR2.Run.Update -= Run_Update; }
private void Run_OnServerTeleporterPlaced(On.RoR2.Run.orig_OnServerTeleporterPlaced orig, Run self, SceneDirector sceneDirector, GameObject teleporter) { orig.Invoke(self, sceneDirector, teleporter); ExampleCommandClientCustom.Invoke(y => { y.Write("Setup"); y.Write(0.0); }); times = new float[PlayerCharacterMasterController.instances.Count]; }
private void RegisterMiniRpcCMDs(MiniRpcInstance miniRpc) { // This command will be called by a client (including the host), and executed on the server (host) ExampleCommandHostCustom = miniRpc.RegisterAction(Target.Server, (user, x) => { // This is what the server will execute when a client invokes the IRpcAction var str = x.ReadString(); Debug.Log($"[Host] {user?.userName} sent us: {str}"); if (str == "Buymenu") { //Get a user id, starts from 0 List <NetworkUser> instancesList = typeof(NetworkUser).GetFieldValue <List <NetworkUser> >("instancesList"); int id = instancesList.IndexOf(user); if (id < 0) { return; } //When the id is bigger than the count add items, with a default value of false if (AllBuyMenuStates.Count - 1 < id) { for (int i = AllBuyMenuStates.Count - 1; i < id; i++) { AllBuyMenuStates.Add(false); } } //Didnt work with Boolean ... var doubleVal = x.ReadDouble(); //Workaround bool state = doubleVal == 0.0 ? false : true; AllBuyMenuStates[id] = state; //Check if any one has the select menu open int check = AllBuyMenuStates.FindAll(a => a == true).Count; Debug.Log(check); //If at least one has it opened set the Timescale to the config one //Else set it back to 1.0 if (check > 0) { ExampleCommandClientCustom.Invoke(y => { y.Write("Timescale"); //Convert to double y.Write((double)config.TimeScale); }); } else { ExampleCommandClientCustom.Invoke(y => { y.Write("Timescale"); y.Write(1.0); }); } } if (str == "CreatePickupDroplet_Item") { ItemIndex item = x.ReadItemIndex(); PickupIndex pickupIndex = new PickupIndex(item); Transform chestTransform = x.ReadTransform(); Vector3 pos = chestTransform.position; Vector3 forward = chestTransform.position; RoR2.PickupDropletController.CreatePickupDroplet(pickupIndex, pos + Vector3.up * 1.5f, Vector3.up * 20f + forward * 2f); } if (str == "CreatePickupDroplet_Equipment") { EquipmentIndex item = x.ReadEquipmentIndex(); PickupIndex pickupIndex = new PickupIndex(item); Transform chestTransform = x.ReadTransform(); Vector3 pos = chestTransform.position; Vector3 forward = chestTransform.position; RoR2.PickupDropletController.CreatePickupDroplet(pickupIndex, pos + Vector3.up * 1.5f, Vector3.up * 20f + forward * 2f); } }); // This command will be called by the host, and executed on all clients ExampleCommandClientCustom = miniRpc.RegisterAction(Target.Client, (user, x) => { // This is what all clients will execute when the server invokes the IRpcAction var str = x.ReadString(); Debug.Log($"[Client] Host sent us: {str}"); if (str == "Reset") { bool everything_Avaiable = x.ReadBoolean(); Debug.Log("BOOL TEST:" + everything_Avaiable); playerCharacterMaster = null; //Get the local player if (this.playerCharacterMaster == null) { this.playerCharacterMaster = LocalUserManager.GetFirstLocalUser().cachedMasterController; } //If the local player isnt setup yet, set him up if (this.playerCharacterMaster.GetComponent <CA_PlayerScript>() == null) { this.playerCharacterMaster.gameObject.AddComponent <CA_PlayerScript>(); this.playerCharacterMaster.gameObject.GetComponent <CA_PlayerScript>().ExampleCommandHostCustom = this.ExampleCommandHostCustom; this.playerCharacterMaster.gameObject.GetComponent <CA_PlayerScript>().config = config; this.playerCharacterMaster.gameObject.GetComponent <CA_PlayerScript>().Everything_Avaiable = everything_Avaiable; this.playerCharacterMaster.gameObject.GetComponent <CA_PlayerScript>().AwakeManual(); } } if (str == "Chest") { //Get transfered variables GameObject interactor = x.ReadGameObject(); Transform transform = x.ReadTransform(); double tier = x.ReadDouble(); CA_PlayerScript playerScript = this.playerCharacterMaster.gameObject.GetComponent <CA_PlayerScript>(); //Check the player that opened the chest is correctly setup if (!playerScript) { return; } GameObject activator = interactor.GetComponent <CharacterBody>().gameObject; GameObject thisGO = this.playerCharacterMaster.master.GetBody().gameObject; //Check if this local player is the one that opened the chest if (activator != thisGO) { return; } // RNG Value was above specified percantage values // Cancel the drop if ((int)tier == 0) { Chat.AddMessage("Mhh Unlucky you found nothing in this Chest."); return; } //Add the items to the UI and Unhide the SelectMenu playerScript.AddTierToGUI((int)tier, transform); playerScript.SetBuyMenu(true); return; } if (str == "Timescale") { var floatVal = (float)x.ReadDouble(); Time.timeScale = floatVal; } }); // -1 = Error/Not Same || 1 = Same but not idling || 0 = Same and idling ExampleFuncClient = miniRpc.RegisterFunc <GameObject, int>(Target.Client, (user, activator) => { CA_PlayerScript playerScript = this.playerCharacterMaster.gameObject.GetComponent <CA_PlayerScript>(); Debug.Log(playerScript != null); if (!playerScript) { return(-1); } GameObject activatorGO = activator.GetComponent <CharacterBody>().gameObject; GameObject thisGO = this.playerCharacterMaster.master.GetBody().gameObject; Debug.Log(activatorGO == thisGO); if (activatorGO != thisGO) { return(-1); } Debug.Log(playerScript.isChestOpening); if (playerScript.isChestOpening) { return(1); } return(0); }); }
private void PurchaseInteraction_OnInteractionBegin(On.RoR2.PurchaseInteraction.orig_OnInteractionBegin orig, RoR2.PurchaseInteraction self, RoR2.Interactor activator) { //Get the lowercase name of the Interacted Object string objName = self.gameObject.name.ToLower(); //Check if its a supported Chest if (!objName.Contains("chest1") && !objName.Contains("chest2") && !objName.Contains("goldchest") && !objName.Contains("equipmentbarrel") && !objName.Contains("isclockbox")) { orig.Invoke(self, activator); return; } //Get the chest type //Too lazy and tired to make it prettier int chestType = objName.Contains("chest1") ? 0 : objName.Contains("chest2") ? 1 : objName.Contains("goldchest") ? 2 : objName.Contains("isclockbox") ? 3 : -1; //Randomly Select Tier double tier = GetRandomTier(chestType); //Send every client a message that a chest has been opened ExampleFuncClient.Invoke(activator.gameObject, check => { //Check which client opened the chest and wheter or not he is idling Debug.Log("Check: " + check); if (check == 0) { orig.Invoke(self, activator); } if (check != 0) { return; } if (objName.Contains("equipmentbarrel")) { //Signal the server that a chest has been opened //Give the player that opend it and the chest position ExampleCommandClientCustom.Invoke(x => { x.Write("Chest"); x.Write(activator.gameObject); x.Write(self.gameObject.transform); //Specify tier as Equipment x.Write((double)6); }); } else { // RNG Value was above specified percantage values // Cancel the drop /*if (tier == 0) * { * Debug.Log("Mhh Unlucky you found nothing in this Chest."); * return; * }*/ //Signal the server that a chest has been opened //Give the player that opend it and the chest position ExampleCommandClientCustom.Invoke(x => { x.Write("Chest"); x.Write(activator.gameObject); x.Write(self.gameObject.transform); x.Write(tier); }); } }); }
public async void Update() { // If we hit PageUp on a client, execute ExampleCommandHost on the server with the parameter "C2S!" if (Input.GetKeyDown(KeyCode.PageUp)) { ExampleCommandHost.Invoke("C2S!"); } // If we hit PageUp on the server, execute ExampleCommandClient on all clients (including ourselves) with the parameter "S2C!" if (Input.GetKeyDown(KeyCode.PageDown)) { ExampleCommandClient.Invoke("S2C!"); } // If we hit Home on the client, execute ExampleCommandHostCustom on the server, which writes a custom message as "parameter" if (Input.GetKeyDown(KeyCode.Home)) { ExampleCommandHostCustom.Invoke(x => { x.Write("Test C2S"); x.Write(2); }); } // If we hit End on the server, execute ExampleCommandHostCustom on all clients, which writes a custom message as "parameter" if (Input.GetKeyDown(KeyCode.End)) { ExampleCommandClientCustom.Invoke(x => { x.Write("Test S2C"); x.Write(4); }); } if (Input.GetKeyDown(KeyCode.Insert)) { Debug.Log("[MiniRpcDemo] Sending request ExampleFuncHost."); ExampleFuncHost.Invoke(true, result => { Debug.Log($"[MiniRpcDemo] Received response ExampleFuncHost: {result}"); }); } if (Input.GetKeyDown(KeyCode.Delete)) { Debug.Log("[MiniRpcDemo] Sending request ExampleFuncClient."); ExampleFuncClient.Invoke(true, result => { Debug.Log($"[MiniRpcDemo] Received response ExampleFuncClient: {result}"); }); } if (Input.GetKeyDown(KeyCode.UpArrow)) { Debug.Log("[MiniRpcDemo] Sending request ExampleFuncClientObject."); ExampleFuncClientObject.Invoke(new ExampleObject(true, 28, "Pure"), result => { Debug.Log($"[MiniRpcDemo] Received response ExampleFuncClientObject: {result}"); }); } }
private void RegisterMiniRpcCommands(MiniRpcInstance miniRpc) { ExampleCommandHost = miniRpc.RegisterAction(Target.Server, (NetworkUser user, string x) => Debug.Log($"[Host] {user?.userName} sent us: {x}")); ExampleCommandClient = miniRpc.RegisterAction(Target.Client, (NetworkUser user, string x) => Debug.Log($"[Client] Host sent us: {x}")); // This command will be called by a client (including the host), and executed on the server (host) ExampleCommandHostCustom = miniRpc.RegisterAction(Target.Server, (user, x) => { // This is what the server will execute when a client invokes the IRpcAction var str = x.ReadString(); var doubleVal = x.ReadDouble(); Debug.Log($"[Host] {user?.userName} sent us: {str} {doubleVal}"); if (str == "Time") { List <NetworkUser> instancesList = typeof(NetworkUser).GetFieldValue <List <NetworkUser> >("instancesList"); int id = instancesList.IndexOf(user); if (id < 0) { return; } //Debug.Log("ID: " + id); times[id] = ((float)doubleVal / times.Length); float timeScale = 0.0f; for (int i = 0; i < times.Length; i++) { timeScale += times[i]; } ExampleCommandClientCustom.Invoke(y => { y.Write("SetTimeScale"); y.Write((double)timeScale); }); } }); // This command will be called by the host, and executed on all clients ExampleCommandClientCustom = miniRpc.RegisterAction(Target.Client, (user, x) => { // This is what all clients will execute when the server invokes the IRpcAction var str = x.ReadString(); var doubleVal = x.ReadDouble(); float floatVal = (float)doubleVal; Debug.Log($"[Client] Host sent us: {str} {floatVal}"); if (str == "SetTimeScale") { /* * Todo Add config */ if (floatVal < .1f) { floatVal = .1f; } Time.timeScale = floatVal; } if (str == "Setup") { characterBody = LocalUserManager.GetFirstLocalUser().cachedBody; inputPlayer = LocalUserManager.GetFirstLocalUser().inputPlayer; characterMotor = LocalUserManager.GetFirstLocalUser().cachedBodyObject.GetComponent <CharacterMotor>(); On.RoR2.Run.Update += Run_Update; } }); }