Added more console feed back and fixed the TP command when used on a a player other than the current one. Prepped the animations for modularization. Moved version to 1510.

This commit is contained in:
Twirlbug 2023-07-05 21:02:05 -05:00
parent 1d86b05a62
commit 84419debcf
7 changed files with 242 additions and 117 deletions

View file

@ -1,17 +1,17 @@
# srmp-public # srmp-public
This is the code for the Slime Rancher MultiPlayer Mod (SRMP). Currently working on going through the code, adding notes and fixing some of the bugs in my free time.
I adore this mod and want to give both credit and a huge thank you to Saty for the origional creation of the mod.
The suer manual can be found [here](/manual.md).
I am slowly working my way through the list of bugs as seen below.
## Bug Status # Bug Status
Notes: Bug list compiled from last known bug list of version 1488 Notes: Bug list compiled from last known bug list of version 1488
FIXED: FIXED:
- Multiplayer window doesn't show up on resolutions < 1920x1080 - Multiplayer window doesn't show up on resolutions < 1920x1080
IN PROGRESS (NEEDS MORE TESTING):
- Exchange sometimes skips rewards if multiple players put items in at the same time - Exchange sometimes skips rewards if multiple players put items in at the same time
- Exchange chest disappears without rewards - Exchange chest disappears without rewards
@ -30,20 +30,14 @@ Known Bugs:
- Upgrades sometimes does not get applied to All players - Upgrades sometimes does not get applied to All players
##Current Status #Notes Status
@Twirlbug Files in the following folders still need notes:
- Currently working on going through the code, adding notes and fixing some of the bugs in my free time.
- I adore this mod and want to give both credit and a huge thank you to Saty for the origional creation of the mod.
I am slowly working my way through the list of bugs as seen above.
###Notation Status
Files in the following folders still need more notation:
- Networking - Networking
- Packets - Packets
- Patches - Patches
--------------------------------------------------------------------------------- ---------------------------------------------------------------------------------
##Origional File From SatyPardus
Origional File From SatyPardus
It's bad. It's really really bad. It's bad. It's really really bad.

View file

@ -290,6 +290,7 @@ namespace SRMultiplayer
//mark target transform location //mark target transform location
PacketPlayerPosition packet = null; PacketPlayerPosition packet = null;
string destSummary = "";
//first check distination //first check distination
switch (destination.ToLower()) switch (destination.ToLower())
@ -304,7 +305,7 @@ namespace SRMultiplayer
RegionSet = (byte)home.GetRegionSetId() RegionSet = (byte)home.GetRegionSetId()
}; };
destSummary = "Home";
break; break;
default: //check for a player name default: //check for a player name
var play = Globals.Players.Values.FirstOrDefault(p => p.Username.Equals(destination, StringComparison.CurrentCultureIgnoreCase)); var play = Globals.Players.Values.FirstOrDefault(p => p.Username.Equals(destination, StringComparison.CurrentCultureIgnoreCase));
@ -320,7 +321,7 @@ namespace SRMultiplayer
Rotation = play.transform.eulerAngles.y, Rotation = play.transform.eulerAngles.y,
RegionSet = (byte)play.CurrentRegionSet RegionSet = (byte)play.CurrentRegionSet
}; };
destSummary = play.Username;
break; break;
} }
@ -346,10 +347,12 @@ namespace SRMultiplayer
return; return;
} }
ConsoleLog("Teleporting " + targetPlayer.Username + " to " + destSummary);
if (!targetPlayer.IsLocal) if (!targetPlayer.IsLocal)
{ {
//if a target is located and is not the local player send the teleport command //if a target is located and is not the local player send the teleport command
packet.ID = targetPlayer.ID;
packet.WeaponY = targetPlayer.GetWeaponLocation(); packet.WeaponY = targetPlayer.GetWeaponLocation();
packet.Send(); packet.Send();
return; return;
@ -361,6 +364,8 @@ namespace SRMultiplayer
SRSingleton<SceneContext>.Instance.player.transform.position = packet.Position; SRSingleton<SceneContext>.Instance.player.transform.position = packet.Position;
SRSingleton<SceneContext>.Instance.player.transform.eulerAngles = new Vector3(0, packet.Rotation, 0); SRSingleton<SceneContext>.Instance.player.transform.eulerAngles = new Vector3(0, packet.Rotation, 0);
SRSingleton<SceneContext>.Instance.PlayerState.model.SetCurrRegionSet((RegionRegistry.RegionSetId)packet.RegionSet); SRSingleton<SceneContext>.Instance.PlayerState.model.SetCurrRegionSet((RegionRegistry.RegionSetId)packet.RegionSet);
// play the teleport animation
SRSingleton<Overlay>.Instance.PlayTeleport();
} }
} }

View file

@ -1,15 +1,12 @@
using DG.Tweening; using DG.Tweening;
using Lidgren.Network; using Lidgren.Network;
using MonomiPark.SlimeRancher.DataModel; using MonomiPark.SlimeRancher.DataModel;
using MonomiPark.SlimeRancher.Persist;
using MonomiPark.SlimeRancher.Regions; using MonomiPark.SlimeRancher.Regions;
using SRMultiplayer.Packets; using SRMultiplayer.Packets;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine; using UnityEngine;
namespace SRMultiplayer.Networking namespace SRMultiplayer.Networking
@ -30,7 +27,7 @@ namespace SRMultiplayer.Networking
case PacketType.PlayerJoined: OnPlayerJoined(new PacketPlayerJoined(im)); break; case PacketType.PlayerJoined: OnPlayerJoined(new PacketPlayerJoined(im)); break;
case PacketType.PlayerLeft: OnPlayerLeft(new PacketPlayerLeft(im)); break; case PacketType.PlayerLeft: OnPlayerLeft(new PacketPlayerLeft(im)); break;
case PacketType.PlayerLoaded: OnPlayerLoaded(new PacketPlayerLoaded(im)); break; case PacketType.PlayerLoaded: OnPlayerLoaded(new PacketPlayerLoaded(im)); break;
case PacketType.PlayerPosition: OnPlayerPosition(new PacketPlayerPosition(im)); break; case PacketType.PlayerPosition: OnPlayerPosition(new PacketPlayerPosition(im)); break;
case PacketType.PlayerFX: OnPlayerFX(new PacketPlayerFX(im)); break; case PacketType.PlayerFX: OnPlayerFX(new PacketPlayerFX(im)); break;
case PacketType.PlayerCurrency: OnPlayerCurrency(new PacketPlayerCurrency(im)); break; case PacketType.PlayerCurrency: OnPlayerCurrency(new PacketPlayerCurrency(im)); break;
case PacketType.PlayerCurrencyDisplay: OnPlayerCurrencyDisplay(new PacketPlayerCurrencyDisplay(im)); break; case PacketType.PlayerCurrencyDisplay: OnPlayerCurrencyDisplay(new PacketPlayerCurrencyDisplay(im)); break;
@ -151,7 +148,7 @@ namespace SRMultiplayer.Networking
// Race // Race
case PacketType.RaceActivate: OnRaceActivate(new PacketRaceActivate(im)); break; case PacketType.RaceActivate: OnRaceActivate(new PacketRaceActivate(im)); break;
case PacketType.RaceEnd: OnRaceEnd(new PacketRaceEnd(im)); break; case PacketType.RaceEnd: OnRaceEnd(new PacketRaceEnd(im)); break;
case PacketType.RaceTime: OnRaceTime(new PacketRaceTime(im)); break; case PacketType.RaceTime: OnRaceTime(new PacketRaceTime(im)); break;
case PacketType.RaceTrigger: OnRaceTrigger(new PacketRaceTrigger(im)); break; case PacketType.RaceTrigger: OnRaceTrigger(new PacketRaceTrigger(im)); break;
default: default:
SRMP.Log($"Got unhandled packet: {type} " + Enum.GetName(typeof(PacketType), type)); SRMP.Log($"Got unhandled packet: {type} " + Enum.GetName(typeof(PacketType), type));
@ -372,7 +369,7 @@ namespace SRMultiplayer.Networking
//send off fireworks //send off fireworks
SRBehaviour.InstantiateDynamic(eject.awardFX, eject.awardAt.position, eject.awardAt.rotation); SRBehaviour.InstantiateDynamic(eject.awardFX, eject.awardAt.position, eject.awardAt.rotation);
} }
//dont clear out the offer yet, we arent done with it //dont clear out the offer yet, we arent done with it
//SRSingleton<SceneContext>.Instance.ExchangeDirector.ClearOffer(type); //SRSingleton<SceneContext>.Instance.ExchangeDirector.ClearOffer(type);
} }
@ -383,7 +380,7 @@ namespace SRMultiplayer.Networking
} }
} }
} }
private static void OnExchangePrepareDaily(PacketExchangePrepareDaily packet) private static void OnExchangePrepareDaily(PacketExchangePrepareDaily packet)
{ {
SRSingleton<SceneContext>.Instance.ExchangeDirector.worldModel.pendingOfferRancherIds = packet.pendingOfferRancherIds; SRSingleton<SceneContext>.Instance.ExchangeDirector.worldModel.pendingOfferRancherIds = packet.pendingOfferRancherIds;
SRSingleton<SceneContext>.Instance.ExchangeDirector.OfferDidChange(); SRSingleton<SceneContext>.Instance.ExchangeDirector.OfferDidChange();
@ -1940,7 +1937,9 @@ namespace SRMultiplayer.Networking
if(type == PacketPlayerAnimation.AnimationType.Speed) if(type == PacketPlayerAnimation.AnimationType.Speed)
player.ReadAnimatorSpeed(packet.internalData); player.ReadAnimatorSpeed(packet.internalData);
else if (type == PacketPlayerAnimation.AnimationType.Parameters) else if (type == PacketPlayerAnimation.AnimationType.Parameters)
{
player.ReadParameters(packet.internalData); player.ReadParameters(packet.internalData);
}
else else
player.ReadAnimatorLayer(packet.internalData); player.ReadAnimatorLayer(packet.internalData);
} }
@ -1954,59 +1953,74 @@ namespace SRMultiplayer.Networking
{ {
if (player.IsLocal) if (player.IsLocal)
{ {
var euler = SRSingleton<SceneContext>.Instance.player.GetComponentInChildren<WeaponVacuum>().transform.eulerAngles; if (packet.OnLoad)
euler.x = packet.WeaponY;
SRSingleton<SceneContext>.Instance.player.GetComponentInChildren<WeaponVacuum>().transform.eulerAngles = euler;
SRSingleton<SceneContext>.Instance.player.transform.position = packet.Position;
SRSingleton<SceneContext>.Instance.player.transform.eulerAngles = new Vector3(0, packet.Rotation, 0);
SRSingleton<SceneContext>.Instance.PlayerState.model.SetCurrRegionSet((RegionRegistry.RegionSetId)packet.RegionSet);
//only reload inventory if this is a load up packet and NOT a tp packet
if (!Globals.IsServer && packet.OnLoad)
{ {
try
var euler = SRSingleton<SceneContext>.Instance.player.GetComponentInChildren<WeaponVacuum>().transform.eulerAngles;
euler.x = packet.WeaponY;
SRSingleton<SceneContext>.Instance.player.GetComponentInChildren<WeaponVacuum>().transform.eulerAngles = euler;
SRSingleton<SceneContext>.Instance.player.transform.position = packet.Position;
SRSingleton<SceneContext>.Instance.player.transform.eulerAngles = new Vector3(0, packet.Rotation, 0);
SRSingleton<SceneContext>.Instance.PlayerState.model.SetCurrRegionSet((RegionRegistry.RegionSetId)packet.RegionSet);
//only reload inventory if this is a load up packet and NOT a tp packet
if (!Globals.IsServer)
{ {
using (FileStream file = new FileStream(Path.Combine(SRMP.ModDataPath, Globals.CurrentGameName + ".player"), FileMode.Open)) try
{ {
using (BinaryReader reader = new BinaryReader(file)) using (FileStream file = new FileStream(Path.Combine(SRMP.ModDataPath, Globals.CurrentGameName + ".player"), FileMode.Open))
{ {
Debug.Log($"Loading {Path.Combine(SRMP.ModDataPath, Globals.CurrentGameName + ".player")}"); using (BinaryReader reader = new BinaryReader(file))
var ammoCount = reader.ReadInt32();
for (int i = 0; i < ammoCount; i++)
{ {
var state = (PlayerState.AmmoMode)reader.ReadByte(); Debug.Log($"Loading {Path.Combine(SRMP.ModDataPath, Globals.CurrentGameName + ".player")}");
SRSingleton<SceneContext>.Instance.PlayerState.model.ammoDict[state].usableSlots = reader.ReadInt32(); var ammoCount = reader.ReadInt32();
var slotCount = reader.ReadInt32(); for (int i = 0; i < ammoCount; i++)
SRSingleton<SceneContext>.Instance.PlayerState.model.ammoDict[state].slots = new Ammo.Slot[slotCount];
for (int j = 0; j < slotCount; j++)
{ {
if (reader.ReadBoolean()) var state = (PlayerState.AmmoMode)reader.ReadByte();
SRSingleton<SceneContext>.Instance.PlayerState.model.ammoDict[state].usableSlots = reader.ReadInt32();
var slotCount = reader.ReadInt32();
SRSingleton<SceneContext>.Instance.PlayerState.model.ammoDict[state].slots = new Ammo.Slot[slotCount];
for (int j = 0; j < slotCount; j++)
{ {
SRSingleton<SceneContext>.Instance.PlayerState.model.ammoDict[state].slots[j] = new Ammo.Slot((Identifiable.Id)reader.ReadUInt16(), reader.ReadInt32());
if (reader.ReadBoolean()) if (reader.ReadBoolean())
{ {
SRSingleton<SceneContext>.Instance.PlayerState.model.ammoDict[state].slots[j].emotions = new SlimeEmotionData(); SRSingleton<SceneContext>.Instance.PlayerState.model.ammoDict[state].slots[j] = new Ammo.Slot((Identifiable.Id)reader.ReadUInt16(), reader.ReadInt32());
var emotionCount = reader.ReadInt32(); if (reader.ReadBoolean())
for (int k = 0; k < emotionCount; k++)
{ {
SRSingleton<SceneContext>.Instance.PlayerState.model.ammoDict[state].slots[j].emotions.Add((SlimeEmotions.Emotion)reader.ReadUInt16(), reader.ReadSingle()); SRSingleton<SceneContext>.Instance.PlayerState.model.ammoDict[state].slots[j].emotions = new SlimeEmotionData();
var emotionCount = reader.ReadInt32();
for (int k = 0; k < emotionCount; k++)
{
SRSingleton<SceneContext>.Instance.PlayerState.model.ammoDict[state].slots[j].emotions.Add((SlimeEmotions.Emotion)reader.ReadUInt16(), reader.ReadSingle());
}
} }
} }
} else
else {
{ SRSingleton<SceneContext>.Instance.PlayerState.model.ammoDict[state].slots[j] = null;
SRSingleton<SceneContext>.Instance.PlayerState.model.ammoDict[state].slots[j] = null; }
} }
} }
} }
} }
} }
catch (Exception ex)
{
Debug.Log($"No savefile for {Globals.CurrentGameName}: {ex.Message}");
}
} }
catch (Exception ex) }
{ else
Debug.Log($"No savefile for {Globals.CurrentGameName}: {ex.Message}"); {
} SRMP.Log("Player is being teleported", "CLIENT");
SRSingleton<SceneContext>.Instance.player.transform.position = packet.Position;
SRSingleton<SceneContext>.Instance.player.transform.eulerAngles = new Vector3(0, packet.Rotation, 0);
SRSingleton<SceneContext>.Instance.PlayerState.model.SetCurrRegionSet((RegionRegistry.RegionSetId)packet.RegionSet);
SRSingleton<Overlay>.Instance.PlayTeleport();
} }
} }
else else

View file

@ -335,7 +335,7 @@ namespace SRMultiplayer.Networking
} }
} }
packet.SendToAllExcept(player); packet.SendToAllExcept(player);
} }
private static void OnExchangePrepareDaily(PacketExchangePrepareDaily packet, NetworkPlayer player) private static void OnExchangePrepareDaily(PacketExchangePrepareDaily packet, NetworkPlayer player)
{ {
@ -1650,27 +1650,42 @@ namespace SRMultiplayer.Networking
break; break;
case (byte)PacketPlayerAnimation.AnimationType.Layer: case (byte)PacketPlayerAnimation.AnimationType.Layer:
player.ReadAnimatorLayer(packet.internalData); player.ReadAnimatorLayer(packet.internalData);
break; break;
case (byte)PacketPlayerAnimation.AnimationType.Parameters: case (byte)PacketPlayerAnimation.AnimationType.Parameters:
player.ReadParameters(packet.internalData); player.ReadParameters(packet.internalData);
break; break;
} }
//make the incoming message an out going message //make the incoming message an out going message
packet.SendToAllExcept(player, NetDeliveryMethod.Unreliable); packet.SendToAllExcept(player, NetDeliveryMethod.Unreliable);
} }
} }
private static void OnPlayerPosition(PacketPlayerPosition packet, NetworkPlayer player) private static void OnPlayerPosition(PacketPlayerPosition packet, NetworkPlayer netPlayer)
{ {
//get player id from packet in case of a teleport
NetworkPlayer player = Globals.Players.Values.FirstOrDefault(p => p.ID.Equals(packet.ID));
if (player.HasLoaded) if (player.HasLoaded)
{ {
player.PositionRotationUpdate(packet.Position, packet.Rotation, false); if (player.IsLocal) //if the server player is the one being moved, teleport them
player.UpdateWeaponRotation(packet.WeaponY); {
player.CurrentRegionSet = (RegionRegistry.RegionSetId)packet.RegionSet; SRSingleton<SceneContext>.Instance.player.transform.position = packet.Position;
SRSingleton<SceneContext>.Instance.player.transform.eulerAngles = new Vector3(0, packet.Rotation, 0);
SRSingleton<SceneContext>.Instance.PlayerState.model.SetCurrRegionSet((RegionRegistry.RegionSetId)packet.RegionSet);
packet.ID = player.ID; SRSingleton<Overlay>.Instance.PlayTeleport();
packet.SendToAllExcept(player, NetDeliveryMethod.Unreliable); }
else //else process player movement
{
player.PositionRotationUpdate(packet.Position, packet.Rotation, false);
player.UpdateWeaponRotation(packet.WeaponY);
player.CurrentRegionSet = (RegionRegistry.RegionSetId)packet.RegionSet;
packet.ID = player.ID;
packet.SendToAllExcept(netPlayer, NetDeliveryMethod.Unreliable);
}
} }
} }

View file

@ -1,12 +1,10 @@
using Lidgren.Network; using Lidgren.Network;
using SRMultiplayer.Packets; using SRMultiplayer.Packets;
using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine; using UnityEngine;
using static SRMultiplayer.Packets.PacketPlayerAnimation;
namespace SRMultiplayer.Networking namespace SRMultiplayer.Networking
{ {
@ -68,37 +66,36 @@ namespace SRMultiplayer.Networking
var packet = new PacketPlayerAnimation() var packet = new PacketPlayerAnimation()
{ {
Type = (byte)PacketPlayerAnimation.AnimationType.Layer, Type = (byte)PacketPlayerAnimation.AnimationType.Layer,
ID = Globals.LocalID, ID = Globals.LocalID
internalData = new NetBuffer()
}; };
//add extra parameters //add extra parameters
WriteAnimatorLayer(packet.internalData, stateHash, normalizedTime, i, layerWeight[i]); WriteAnimatorLayer(packet, stateHash, normalizedTime, i, layerWeight[i]);
//send the changes //send the changes
//packet.Send(); packet.Send();
} }
CheckSpeed(); CheckSpeed();
} }
void WriteAnimatorLayer(NetBuffer writer, int stateHash, float normalizedTime, int layerNumber, float layerWeight) void WriteAnimatorLayer(PacketPlayerAnimation writer, int stateHash, float normalizedTime, int layerNumber, float layerWeight)
{ {
writer.Write(stateHash); writer.Add(stateHash);
writer.Write(normalizedTime); writer.Add(normalizedTime);
writer.Write(layerNumber); writer.Add(layerNumber);
writer.Write(layerWeight); writer.Add(layerWeight);
WriteParameters(writer); WriteParameters(writer);
} }
public void ReadAnimatorLayer(NetBuffer im) public void ReadAnimatorLayer(Queue<animateData> im)
{ {
if (m_Animator == null) return; if (m_Animator == null) return;
int stateHash = im.ReadInt32(); int stateHash = im.Dequeue().iData.Value;
float normalizedTime = im.ReadFloat(); float normalizedTime = im.Dequeue().fData.Value;
int layerNumber = im.ReadInt32(); int layerNumber = im.Dequeue().iData.Value;
float layerWeight = im.ReadFloat(); float layerWeight = im.Dequeue().fData.Value;
if (stateHash != 0 && m_Animator.enabled) if (stateHash != 0 && m_Animator.enabled)
{ {
@ -122,28 +119,27 @@ namespace SRMultiplayer.Networking
var packet = new PacketPlayerAnimation() var packet = new PacketPlayerAnimation()
{ {
Type = (byte)PacketPlayerAnimation.AnimationType.Speed, Type = (byte)PacketPlayerAnimation.AnimationType.Speed,
ID = Globals.LocalID, ID = Globals.LocalID
internalData = new NetBuffer()
}; };
//add extra parameters //add extra parameters
WriteAnimatorSpeed(packet.internalData, newSpeed); WriteAnimatorSpeed(packet, newSpeed);
//send the speed change //send the speed change
//packet.Send(); packet.Send();
} }
} }
void WriteAnimatorSpeed(NetBuffer writer, float newSpeed) void WriteAnimatorSpeed(PacketPlayerAnimation writer, float newSpeed)
{ {
writer.Write(newSpeed); writer.Add(newSpeed);
} }
public void ReadAnimatorSpeed(NetBuffer im) public void ReadAnimatorSpeed(Queue<animateData> im)
{ {
if (m_Animator == null) return; if (m_Animator == null) return;
var newSpeed = im.ReadFloat(); var newSpeed = im.Dequeue().fData.Value;
// set m_Animator // set m_Animator
m_Animator.speed = newSpeed; m_Animator.speed = newSpeed;
m_AnimatorSpeed = newSpeed; m_AnimatorSpeed = newSpeed;
@ -203,14 +199,14 @@ namespace SRMultiplayer.Networking
var packet = new PacketPlayerAnimation() var packet = new PacketPlayerAnimation()
{ {
Type = (byte)PacketPlayerAnimation.AnimationType.Parameters, Type = (byte)PacketPlayerAnimation.AnimationType.Parameters,
ID = Globals.LocalID, ID = Globals.LocalID
internalData = new NetBuffer()
}; };
//add extra parameters //add extra parameters
WriteParameters(packet.internalData); if (WriteParameters(packet))
{
//packet.Send(); packet.Send();
}
} }
} }
@ -251,10 +247,10 @@ namespace SRMultiplayer.Networking
return dirtyBits; return dirtyBits;
} }
bool WriteParameters(NetBuffer writer, bool forceAll = false) bool WriteParameters(PacketPlayerAnimation writer, bool forceAll = false)
{ {
ulong dirtyBits = forceAll ? (~0ul) : NextDirtyBits(); ulong dirtyBits = forceAll ? (~0ul) : NextDirtyBits();
writer.Write(dirtyBits); writer.Add(dirtyBits);
for (int i = 0; i < parameters.Length; i++) for (int i = 0; i < parameters.Length; i++)
{ {
if ((dirtyBits & (1ul << i)) == 0) if ((dirtyBits & (1ul << i)) == 0)
@ -264,53 +260,55 @@ namespace SRMultiplayer.Networking
if (par.type == AnimatorControllerParameterType.Int) if (par.type == AnimatorControllerParameterType.Int)
{ {
int newIntValue = m_Animator.GetInteger(par.nameHash); int newIntValue = m_Animator.GetInteger(par.nameHash);
writer.Write(newIntValue); writer.Add(newIntValue);
} }
else if (par.type == AnimatorControllerParameterType.Float) else if (par.type == AnimatorControllerParameterType.Float)
{ {
float newFloatValue = m_Animator.GetFloat(par.nameHash); float newFloatValue = m_Animator.GetFloat(par.nameHash);
writer.Write(newFloatValue); writer.Add(newFloatValue);
} }
else if (par.type == AnimatorControllerParameterType.Bool) else if (par.type == AnimatorControllerParameterType.Bool)
{ {
bool newBoolValue = m_Animator.GetBool(par.nameHash); bool newBoolValue = m_Animator.GetBool(par.nameHash);
writer.Write(newBoolValue); writer.Add(newBoolValue);
} }
} }
return dirtyBits != 0; return dirtyBits != 0;
} }
public void ReadParameters(NetBuffer reader) public void ReadParameters(Queue<animateData> im)
{ { //make sure
if (m_Animator == null) return; if (m_Animator == null) return;
bool m_AnimatorEnabled = m_Animator.enabled; bool m_AnimatorEnabled = m_Animator.enabled;
// need to read values from NetworkReader even if m_Animator is disabled
ulong dirtyBits = reader.ReadUInt64(); // need to read values from NetworkReader even if m_Animator is disabled
ulong dirtyBits = im.Dequeue().uData.Value;
for (int i = 0; i < parameters.Length; i++) for (int i = 0; i < parameters.Length; i++)
{ {
if ((dirtyBits & (1ul << i)) == 0) if ((dirtyBits & (1ul << i)) == 0)
continue; continue;
AnimatorControllerParameter par = parameters[i]; AnimatorControllerParameter par = parameters[i];
if (par.type == AnimatorControllerParameterType.Int) if (par.type == AnimatorControllerParameterType.Int)
{ {
int newIntValue = reader.ReadInt32(); int? newIntValue = im.Dequeue().iData;
if (m_AnimatorEnabled) if (m_AnimatorEnabled)
m_Animator.SetInteger(par.nameHash, newIntValue); m_Animator.SetInteger(par.nameHash, newIntValue.Value);
} }
else if (par.type == AnimatorControllerParameterType.Float) else if (par.type == AnimatorControllerParameterType.Float)
{ {
float newFloatValue = reader.ReadSingle(); float? newFloatValue = im.Dequeue().fData;
if (m_AnimatorEnabled) if (m_AnimatorEnabled)
m_Animator.SetFloat(par.nameHash, newFloatValue); m_Animator.SetFloat(par.nameHash, newFloatValue.Value);
} }
else if (par.type == AnimatorControllerParameterType.Bool) else if (par.type == AnimatorControllerParameterType.Bool)
{ {
bool newBoolValue = reader.ReadBoolean(); bool? newBoolValue = im.Dequeue().bData;
if (m_AnimatorEnabled) if (m_AnimatorEnabled)
m_Animator.SetBool(par.nameHash, newBoolValue); m_Animator.SetBool(par.nameHash, newBoolValue.Value);
} }
} }
} }

View file

@ -1,9 +1,12 @@
using Lidgren.Network; using Lidgren.Network;
using MonomiPark.SlimeRancher.DataModel;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using static SRMultiplayer.Packets.PacketAccessDoors;
namespace SRMultiplayer.Packets namespace SRMultiplayer.Packets
{ {
@ -20,16 +23,111 @@ namespace SRMultiplayer.Packets
public byte ID; public byte ID;
public byte Type; public byte Type;
public NetBuffer internalData; public struct animateData
{
public byte type
{
get
{
if (fData.HasValue) return 0;
if (bData.HasValue) return 1;
if (iData.HasValue) return 2;
if (uData.HasValue) return 3;
return 8;
}
}
public float? fData;
public bool? bData;
public int? iData;
public ulong? uData;
}
public Queue<animateData> internalData { get; set; } = new Queue<animateData>();
public void Add<T>(T obj)
{
switch (obj)
{
case float itm:
internalData.Enqueue(new animateData() { fData = itm });
break;
case bool itm:
internalData.Enqueue(new animateData() { bData = itm });
break;
case int itm:
internalData.Enqueue(new animateData() { iData = itm });
break;
case ulong itm:
internalData.Enqueue(new animateData() { uData = itm });
break;
}
}
/// <summary> /// <summary>
/// mark construction inheritance incase we need it /// mark construction inheritance incase we need it
/// </summary> /// </summary>
public PacketPlayerAnimation():base() { } public PacketPlayerAnimation() : base() { }
/// <summary> /// <summary>
/// mark construction inheritance so the deserialization automatically happens for is /// mark construction inheritance so the deserialization automatically happens for is
/// since the base decalres this /// since the base decalres this
/// </summary> /// </summary>
public PacketPlayerAnimation(NetIncomingMessage im):base(im) { } public PacketPlayerAnimation(NetIncomingMessage im) : base(im) { }
public override void Serialize(NetOutgoingMessage om)
{
base.Serialize(om);
om.Write(internalData.Count);
foreach (var data in internalData)
{
om.Write(data.type);
switch (data.type)
{
case 0:
om.Write(data.fData.Value);
break;
case 1:
om.Write(data.bData.Value);
break;
case 2:
om.Write(data.iData.Value);
break;
case 3:
om.Write(data.uData.Value);
break;
}
}
}
public override void Deserialize(NetIncomingMessage im)
{
base.Deserialize(im);
internalData = new Queue<animateData>();
int Count = im.ReadInt32();
for (int i = 0; i < Count; i++)
{
var data = new animateData();
byte type = im.ReadByte();
switch (type)
{
case 0:
data.fData = im.ReadFloat();
break;
case 1:
data.bData = im.ReadBoolean();
break;
case 2:
data.iData = im.ReadInt32();
break;
case 3:
data.uData = im.ReadUInt64();
break;
}
internalData.Enqueue(data);
}
}
} }
} }

View file

@ -15,6 +15,7 @@ namespace SRMultiplayer.Packets
public float Rotation; public float Rotation;
public float WeaponY; public float WeaponY;
public byte RegionSet; public byte RegionSet;
public bool OnLoad = true;
public PacketPlayerPosition() { } public PacketPlayerPosition() { }
public PacketPlayerPosition(NetIncomingMessage im) { Deserialize(im); } public PacketPlayerPosition(NetIncomingMessage im) { Deserialize(im); }