Fixes and improvements, no more FindObjectsOfType

This commit is contained in:
Andrej Stojkovikj committed 2026-10-18 03:16:05 +02:00
1 parent a740fec7c8
commit fb002cbf0c
328 files changed
+4318 -299

No files matched your search

+64
View File
@@ -0,0 +1,64 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<LangVersion>latest</LangVersion>
<ImplicitUsings>disable</ImplicitUsings>
<Nullable>disable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<AssemblyName>PeePeeMod</AssemblyName>
<RootNamespace>PeePeeMod</RootNamespace>
<AppendTargetFrameworkToOutputPath>true</AppendTargetFrameworkToOutputPath>
<GameDir Condition="'$(GameDir)' == ''">D:\SteamLibrary\steamapps\common\Skopje83</GameDir>
</PropertyGroup>
<ItemGroup>
<Reference Include="0Harmony">
<HintPath>$(GameDir)\BepInEx\core\0Harmony.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="BepInEx.Core">
<HintPath>$(GameDir)\BepInEx\core\BepInEx.Core.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="BepInEx.Unity.IL2CPP">
<HintPath>$(GameDir)\BepInEx\core\BepInEx.Unity.IL2CPP.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="Il2CppInterop.Runtime">
<HintPath>$(GameDir)\BepInEx\core\Il2CppInterop.Runtime.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="Il2Cppmscorlib">
<HintPath>$(GameDir)\BepInEx\interop\Il2Cppmscorlib.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="SkopjeAssembly">
<HintPath>$(GameDir)\BepInEx\interop\SkopjeAssembly.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="FishNet.Runtime">
<HintPath>$(GameDir)\BepInEx\interop\FishNet.Runtime.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="Archon.SwissArmyLib">
<HintPath>$(GameDir)\BepInEx\interop\Archon.SwissArmyLib.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="Il2CppSystem.Core">
<HintPath>$(GameDir)\BepInEx\interop\Il2CppSystem.Core.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="UnityEngine.CoreModule">
<HintPath>$(GameDir)\BepInEx\interop\UnityEngine.CoreModule.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="UnityEngine.PhysicsModule">
<HintPath>$(GameDir)\BepInEx\interop\UnityEngine.PhysicsModule.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="UnityEngine.InputLegacyModule">
<HintPath>$(GameDir)\BepInEx\interop\UnityEngine.InputLegacyModule.dll</HintPath>
<Private>false</Private>
</Reference>
</ItemGroup>
</Project>
+580
View File
@@ -0,0 +1,580 @@
using System;
using System.Collections.Generic;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using FishNet;
using FishNet.Connection;
using FishNet.Managing.Client;
using FishNet.Managing.Server;
using FishNet.Object;
using FishNet.Serializing;
using FishNet.Transporting;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Injection;
using Skopje.Modding;
using UnityEngine;
namespace PeePeeMod
{
[BepInPlugin(PluginGuid, PluginName, PluginVersion)]
public class PeePeePlugin : BasePlugin
{
public const string PluginGuid = "com.skopje.peepeemod";
public const string PluginName = "PeePeeMod";
public const string PluginVersion = "1.0.0";
internal static ManualLogSource LogSource;
internal static ConfigEntry<bool> Enabled;
internal static ConfigEntry<KeyCode> Key;
internal static ConfigEntry<bool> Toggle;
internal static GameObject Host;
static Harmony _harmony;
static SkopjePlayer _local;
static bool _pissing;
static bool _latched;
static float _nextSend;
static int _errors;
static bool _loggedInput;
static Il2CppSystem.Action _onClientStarted;
static Il2CppSystem.Action _onClientStopped;
static Il2CppSystem.Action<SkopjePlayer> _onPlayerStarted;
static Il2CppSystem.Action<SkopjePlayer> _onPlayerStopped;
static Il2CppSystem.Action _onGameOver;
public override void Load()
{
LogSource = Log;
Enabled = Config.Bind("Pee", "Enabled", true, "Hold the key to piss. Everyone in the session sees the stream.");
Key = Config.Bind("Pee", "Key", KeyCode.P, "Button that starts pissing.");
Toggle = Config.Bind("Pee", "Toggle", false, "Press once to start and again to stop. Off means hold the key, like Postal.");
ClassInjector.RegisterTypeInIl2Cpp<PeeDriver>();
_onClientStarted = DelegateSupport.ConvertDelegate<Il2CppSystem.Action>(new Action(OnClientStarted));
_onClientStopped = DelegateSupport.ConvertDelegate<Il2CppSystem.Action>(new Action(OnClientStopped));
_onPlayerStarted = DelegateSupport.ConvertDelegate<Il2CppSystem.Action<SkopjePlayer>>(new Action<SkopjePlayer>(OnPlayerStarted));
_onPlayerStopped = DelegateSupport.ConvertDelegate<Il2CppSystem.Action<SkopjePlayer>>(new Action<SkopjePlayer>(OnPlayerStopped));
_onGameOver = DelegateSupport.ConvertDelegate<Il2CppSystem.Action>(new Action(OnGameOver));
ModAPI.add_OnClientStarted(_onClientStarted);
ModAPI.add_OnClientStopped(_onClientStopped);
ModAPI.add_OnPlayerStartedClient(_onPlayerStarted);
ModAPI.add_OnPlayerStoppedClient(_onPlayerStopped);
ModAPI.add_OnGameOver(_onGameOver);
_harmony = new Harmony(PluginGuid);
Patch(AccessTools.Method(typeof(ServerManager), "ParseBroadcast"), nameof(PeeNet.BeforeServerBroadcast));
Patch(AccessTools.Method(typeof(ClientManager), "ParseBroadcast"), nameof(PeeNet.BeforeClientBroadcast));
Host = new GameObject("PeePeeMod");
UnityEngine.Object.DontDestroyOnLoad(Host);
Host.hideFlags = HideFlags.HideAndDontSave;
Host.AddComponent<PeeDriver>();
LogSource.LogInfo($"{PluginName} {PluginVersion} loaded. Hold {Key.Value} to piss. The stream is a server RPC relayed to every client.");
}
public override bool Unload()
{
_pissing = false;
_latched = false;
_local = null;
if (_harmony != null)
_harmony.UnpatchSelf();
if (_onClientStarted != null)
ModAPI.remove_OnClientStarted(_onClientStarted);
if (_onClientStopped != null)
ModAPI.remove_OnClientStopped(_onClientStopped);
if (_onPlayerStarted != null)
ModAPI.remove_OnPlayerStartedClient(_onPlayerStarted);
if (_onPlayerStopped != null)
ModAPI.remove_OnPlayerStoppedClient(_onPlayerStopped);
if (_onGameOver != null)
ModAPI.remove_OnGameOver(_onGameOver);
PeeVisual.Clear();
PeePlayers.Clear();
if (Host != null)
{
UnityEngine.Object.Destroy(Host);
Host = null;
}
return true;
}
static void Patch(System.Reflection.MethodInfo method, string prefix)
{
if (method == null)
{
LogSource.LogWarning("Pee RPC hook was not found: " + prefix);
return;
}
_harmony.Patch(method, prefix: new HarmonyMethod(typeof(PeeNet), prefix));
}
internal static void Fail(Exception ex)
{
if (_errors >= 8 || LogSource == null)
return;
_errors++;
LogSource.LogError("PeePeeMod failed: " + ex.Message);
}
internal static void Tick()
{
SkopjePlayer player = FindLocal();
bool want = WantPee(player);
Vector3 aim = player != null ? PeeVisual.AimOf(player) : Vector3.forward;
if (want != _pissing)
{
_pissing = want;
_nextSend = Time.unscaledTime + 0.12f;
if (want && player != null)
PeeVisual.ShowLocal(player, aim);
else if (player != null)
PeeVisual.Hide(player.ObjectId);
if (player != null)
PeeNet.ServerRpc(player, want, aim, true);
}
else if (want && player != null)
{
PeeVisual.ShowLocal(player, aim);
if (Time.unscaledTime >= _nextSend)
{
_nextSend = Time.unscaledTime + 0.12f;
PeeNet.ServerRpc(player, true, aim, false);
}
}
PeeVisual.Tick();
}
static bool WantPee(SkopjePlayer player)
{
if (Enabled == null || !Enabled.Value || player == null || !CanPee(player))
{
_latched = false;
return false;
}
KeyCode key = Key != null ? Key.Value : KeyCode.None;
if (Toggle != null && Toggle.Value)
{
if (Pressed(key))
_latched = !_latched;
return _latched;
}
return Held(key);
}
static bool CanPee(SkopjePlayer player)
{
if (player.IsDead || player.IsFallen || player.IsSpectating || player.IsPaused || player.InInventory)
return false;
if (player.InsideVehicle != null)
return false;
return player.NetworkObject != null && player.NetworkObject.IsSpawned;
}
static SkopjePlayer FindLocal()
{
return _local;
}
static void OnClientStarted()
{
_pissing = false;
_latched = false;
}
static void OnClientStopped()
{
_pissing = false;
_latched = false;
_local = null;
PeeVisual.Clear();
PeePlayers.Clear();
}
static void OnPlayerStarted(SkopjePlayer player)
{
if (player != null && player.IsOwner)
_local = player;
PeePlayers.Remember(player);
}
static void OnPlayerStopped(SkopjePlayer player)
{
if (player != null)
{
PeeVisual.Hide(player.ObjectId);
PeeVisual.Forget(player.ObjectId);
}
PeePlayers.Forget(player);
if (_local == player)
{
_local = null;
_pissing = false;
_latched = false;
}
}
static void OnGameOver()
{
_pissing = false;
_latched = false;
PeeVisual.Clear();
}
static bool Pressed(KeyCode key)
{
if (key == KeyCode.None)
return false;
try
{
return Input.GetKeyDown(key);
}
catch (Exception ex)
{
if (!_loggedInput)
{
_loggedInput = true;
LogSource.LogWarning("Keyboard input is unavailable: " + ex.Message);
}
return false;
}
}
static bool Held(KeyCode key)
{
if (key == KeyCode.None)
return false;
try
{
return Input.GetKey(key);
}
catch (Exception ex)
{
if (!_loggedInput)
{
_loggedInput = true;
LogSource.LogWarning("Keyboard input is unavailable: " + ex.Message);
}
return false;
}
}
}
public class PeeDriver : MonoBehaviour
{
void Update()
{
try
{
PeePeePlugin.Tick();
}
catch (Exception ex)
{
PeePeePlugin.Fail(ex);
}
}
}
static class PeePlayers
{
static readonly Dictionary<int, SkopjePlayer> _players = new Dictionary<int, SkopjePlayer>();
public static void Remember(SkopjePlayer player)
{
if (player == null)
return;
try
{
if (player.NetworkObject == null)
return;
_players[player.ObjectId] = player;
}
catch (Exception)
{
}
}
public static void Forget(SkopjePlayer player)
{
if (player == null)
return;
_players.Remove(player.ObjectId);
}
public static void Clear()
{
_players.Clear();
}
public static SkopjePlayer Find(int objectId)
{
SkopjePlayer player;
if (_players.TryGetValue(objectId, out player))
return player;
return null;
}
}
static class PeeNet
{
const byte Magic = 0xA7;
static readonly ushort Key = Hash("Skopje.PeePeeMod.PeeBroadcast");
static ushort _seq = 1;
static readonly Dictionary<int, float> _relayAt = new Dictionary<int, float>();
static bool _loggedRelay;
static bool _loggedSeen;
public static void ServerRpc(SkopjePlayer player, bool active, Vector3 aim, bool reliable)
{
if (player == null || player.NetworkObject == null || !player.NetworkObject.IsSpawned)
return;
if (!InstanceFinder.IsClientStarted)
return;
if (aim.sqrMagnitude < 0.0001f)
aim = Vector3.forward;
else
aim.Normalize();
ushort seq = _seq++;
if (_seq == 0)
_seq = 1;
Send(true, reliable ? Channel.Reliable : Channel.Unreliable, player.ObjectId, active, aim, seq);
}
public static bool BeforeServerBroadcast(PooledReader reader, NetworkConnection conn, Channel channel)
{
int start = reader != null ? reader.Position : 0;
int end;
int objectId;
bool active;
Vector3 aim;
ushort seq;
if (!TryRead(reader, start, out end, out objectId, out active, out aim, out seq))
return true;
try
{
Relay(conn, channel, objectId, active, aim, seq);
}
catch (Exception ex)
{
PeePeePlugin.Fail(ex);
}
return false;
}
public static bool BeforeClientBroadcast(PooledReader reader, Channel channel)
{
int start = reader != null ? reader.Position : 0;
int end;
int objectId;
bool active;
Vector3 aim;
ushort seq;
if (!TryRead(reader, start, out end, out objectId, out active, out aim, out seq))
return true;
try
{
ObserversRpc(objectId, active, aim, seq);
}
catch (Exception ex)
{
PeePeePlugin.Fail(ex);
}
return false;
}
static void Relay(NetworkConnection conn, Channel channel, int objectId, bool active, Vector3 aim, ushort seq)
{
if (conn == null || !conn.IsAuthenticated || !InstanceFinder.IsServerStarted)
return;
SkopjePlayer player = PeePlayers.Find(objectId);
if (player == null || !Owns(player, conn))
return;
if (active && !Allow(conn.ClientId))
return;
if (!_loggedRelay && PeePeePlugin.LogSource != null)
{
_loggedRelay = true;
PeePeePlugin.LogSource.LogInfo("Pee server RPC accepted. Relaying to observers.");
}
Send(false, channel, objectId, active, aim, seq);
}
static void ObserversRpc(int objectId, bool active, Vector3 aim, ushort seq)
{
SkopjePlayer player = PeePlayers.Find(objectId);
if (player == null || player.IsOwner)
return;
if (!PeeVisual.Accept(objectId, seq))
return;
if (!_loggedSeen && PeePeePlugin.LogSource != null)
{
_loggedSeen = true;
PeePeePlugin.LogSource.LogInfo("Pee observers RPC received.");
}
if (active)
PeeVisual.ShowRemote(player, aim);
else
PeeVisual.Hide(objectId);
}
static bool Owns(SkopjePlayer player, NetworkConnection conn)
{
if (player.Owner == conn)
return true;
return player.OwnerId == conn.ClientId;
}
static bool Allow(int clientId)
{
float now = Time.unscaledTime;
float last;
if (_relayAt.TryGetValue(clientId, out last) && now - last < 0.05f)
return false;
_relayAt[clientId] = now;
return true;
}
static void Send(bool toServer, Channel channel, int objectId, bool active, Vector3 aim, ushort seq)
{
var manager = InstanceFinder.NetworkManager;
if (manager == null || manager.TransportManager == null)
return;
if (toServer && !InstanceFinder.IsClientStarted)
return;
if (!toServer && !InstanceFinder.IsServerStarted)
return;
PooledWriter data = WriterPool.Retrieve();
PooledWriter writer = WriterPool.Retrieve();
try
{
data.WriteByte(Magic);
data.WriteInt32(objectId);
data.WriteBoolean(active);
data.WriteUInt16(seq);
data.WriteSingle(aim.x);
data.WriteSingle(aim.y);
data.WriteSingle(aim.z);
writer.WriteUInt16((ushort)PacketId.Broadcast);
writer.WriteUInt16(Key);
writer.WriteInt32(data.Length);
writer.WriteArraySegment(data.GetArraySegment());
var segment = writer.GetArraySegment();
if (toServer)
manager.TransportManager.SendToServer((byte)channel, segment, true, DataOrderType.Default);
else
manager.TransportManager.SendToClients((byte)channel, segment, true);
}
finally
{
WriterPool.Store(data);
WriterPool.Store(writer);
}
}
static bool TryRead(PooledReader reader, int start, out int end, out int objectId, out bool active, out Vector3 aim, out ushort seq)
{
end = start;
objectId = 0;
active = false;
aim = Vector3.forward;
seq = 0;
if (reader == null)
return false;
try
{
if (reader.Remaining < 2)
return false;
ushort key = reader.ReadUInt16();
if (key != Key)
{
reader.Position = start;
return false;
}
int length = reader.ReadInt32();
int payload = reader.Position;
if (length < 1 || length > 128 || reader.Remaining < length)
{
reader.Position = start;
return false;
}
end = payload + length;
if (reader.ReadByte() != Magic)
{
reader.Position = start;
return false;
}
objectId = reader.ReadInt32();
active = reader.ReadBoolean();
seq = reader.ReadUInt16();
aim = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
reader.Position = end;
return true;
}
catch (Exception ex)
{
PeePeePlugin.Fail(ex);
try
{
reader.Position = start;
}
catch (Exception)
{
}
return false;
}
}
static ushort Hash(string text)
{
unchecked
{
uint hash = 2166136261;
for (int i = 0; i < text.Length; i++)
{
hash *= 16777619;
hash ^= text[i];
}
return (ushort)((hash >> 16) ^ hash);
}
}
}
}
+546
View File
@@ -0,0 +1,546 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
namespace PeePeeMod
{
static class PeeVisual
{
const int Steps = 20;
const int Droplets = 10;
const float StepTime = 0.04f;
const float Speed = 7.5f;
const float SplatterLife = 0.25f;
static readonly Color PeeColor = new Color(1f, 0.92f, 0.05f, 1f);
static readonly Dictionary<int, Stream> _streams = new Dictionary<int, Stream>();
static readonly Dictionary<int, ushort> _seq = new Dictionary<int, ushort>();
static readonly List<Puddle> _puddles = new List<Puddle>();
static readonly List<int> _dropIds = new List<int>();
static readonly Vector3[] _points = new Vector3[Steps];
static Mesh _sphere;
static Mesh _cube;
static Material _material;
static MaterialPropertyBlock _block;
sealed class Stream
{
public int Id;
public SkopjePlayer Player;
public bool Local;
public Vector3 Aim;
public float Heard;
public Transform Hips;
public bool SearchedHips;
public GameObject Root;
public LineRenderer Line;
public Transform[] Drops;
public float[] Seeds;
}
sealed class Puddle
{
public GameObject Object;
public float Born;
public Vector3 Scale;
}
public static Vector3 AimOf(SkopjePlayer player)
{
if (player != null && player.IsOwner && player.SkopjeFPSCamera != null && player.SkopjeFPSCamera.mainCamera != null)
return player.SkopjeFPSCamera.mainCamera.transform.forward;
if (player != null && player.IsOwner && Camera.main != null)
return Camera.main.transform.forward;
Transform body = Body(player);
if (body == null)
return Vector3.forward;
return (body.forward + Vector3.down * 0.45f).normalized;
}
public static void ShowLocal(SkopjePlayer player, Vector3 aim)
{
Show(player, aim, true);
}
public static void ShowRemote(SkopjePlayer player, Vector3 aim)
{
Show(player, aim, false);
}
public static bool Accept(int objectId, ushort seq)
{
ushort last;
if (!_seq.TryGetValue(objectId, out last))
{
_seq[objectId] = seq;
return true;
}
ushort delta = (ushort)(seq - last);
if (delta == 0 || delta >= 32768)
return false;
_seq[objectId] = seq;
return true;
}
public static void Forget(int objectId)
{
_seq.Remove(objectId);
}
public static void Hide(int objectId)
{
Stream stream;
if (!_streams.TryGetValue(objectId, out stream))
return;
_streams.Remove(objectId);
DestroyStream(stream);
}
public static void Clear()
{
foreach (Stream stream in _streams.Values)
DestroyStream(stream);
_streams.Clear();
_seq.Clear();
for (int i = 0; i < _puddles.Count; i++)
{
if (_puddles[i].Object != null)
UnityEngine.Object.Destroy(_puddles[i].Object);
}
_puddles.Clear();
}
public static void Tick()
{
float now = Time.unscaledTime;
_dropIds.Clear();
foreach (KeyValuePair<int, Stream> pair in _streams)
{
Stream stream = pair.Value;
if (stream.Player == null)
{
_dropIds.Add(pair.Key);
continue;
}
if (!stream.Local && now - stream.Heard > 0.5f)
{
_dropIds.Add(pair.Key);
continue;
}
Draw(stream);
}
for (int i = 0; i < _dropIds.Count; i++)
Hide(_dropIds[i]);
for (int i = _puddles.Count - 1; i >= 0; i--)
{
Puddle puddle = _puddles[i];
if (puddle.Object == null)
{
_puddles.RemoveAt(i);
continue;
}
float age = now - puddle.Born;
if (age >= SplatterLife)
{
UnityEngine.Object.Destroy(puddle.Object);
_puddles.RemoveAt(i);
continue;
}
float shrink = 1f - (age / SplatterLife);
puddle.Object.transform.localScale = puddle.Scale * Mathf.Max(0.2f, shrink);
}
}
static void Show(SkopjePlayer player, Vector3 aim, bool local)
{
if (player == null || player.NetworkObject == null || !player.NetworkObject.IsSpawned)
return;
if (aim.sqrMagnitude < 0.0001f)
aim = Vector3.forward;
else
aim.Normalize();
Stream stream;
if (!_streams.TryGetValue(player.ObjectId, out stream) || stream == null)
{
stream = Create(player);
_streams[player.ObjectId] = stream;
}
stream.Player = player;
stream.Local = local;
stream.Aim = aim;
stream.Heard = Time.unscaledTime;
}
static Stream Create(SkopjePlayer player)
{
EnsureArt();
var stream = new Stream();
stream.Id = player.ObjectId;
stream.Player = player;
stream.Root = new GameObject("PeeStream");
if (PeePeePlugin.Host != null)
stream.Root.transform.SetParent(PeePeePlugin.Host.transform, false);
var lineObject = new GameObject("Stream");
lineObject.transform.SetParent(stream.Root.transform, false);
stream.Line = lineObject.AddComponent<LineRenderer>();
stream.Line.positionCount = 0;
stream.Line.startWidth = 0.035f;
stream.Line.endWidth = 0.018f;
stream.Line.numCapVertices = 4;
stream.Line.numCornerVertices = 3;
stream.Line.useWorldSpace = true;
stream.Line.shadowCastingMode = ShadowCastingMode.Off;
stream.Line.receiveShadows = false;
stream.Line.lightProbeUsage = LightProbeUsage.Off;
stream.Line.reflectionProbeUsage = ReflectionProbeUsage.Off;
if (_material != null)
{
stream.Line.material = _material;
Paint(stream.Line.material);
}
stream.Line.startColor = PeeColor;
stream.Line.endColor = PeeColor;
Paint(stream.Line);
stream.Drops = new Transform[Droplets];
stream.Seeds = new float[Droplets];
for (int i = 0; i < Droplets; i++)
{
stream.Drops[i] = MakeDrop(stream.Root.transform, 0.04f);
stream.Seeds[i] = i / (float)Droplets;
}
return stream;
}
static void Draw(Stream stream)
{
if (stream.Line == null)
return;
Vector3 aim = stream.Aim.sqrMagnitude > 0.0001f ? stream.Aim.normalized : Vector3.forward;
Vector3 origin = Origin(stream, aim);
Vector3 velocity = aim * Speed;
Vector3 pos = origin;
int count = 0;
bool landed = false;
RaycastHit landing = default;
for (int i = 0; i < Steps; i++)
{
Vector3 next = pos + velocity * StepTime + 0.5f * Physics.gravity * (StepTime * StepTime);
velocity += Physics.gravity * StepTime;
RaycastHit hit;
if (HitWorld(pos, next, stream.Player.transform, out hit))
{
_points[i] = hit.point;
count = i + 1;
landed = true;
landing = hit;
break;
}
_points[i] = next;
pos = next;
count = i + 1;
}
if (count < 2)
return;
stream.Line.positionCount = count;
for (int i = 0; i < count; i++)
stream.Line.SetPosition(i, _points[i]);
float now = Time.time;
for (int i = 0; i < stream.Drops.Length; i++)
{
if (stream.Drops[i] == null)
continue;
float travel = Mathf.Repeat(now * 1.7f + stream.Seeds[i], 1f);
Vector3 at = Along(_points, count, travel);
Vector3 side = Vector3.Cross(aim, Vector3.up);
if (side.sqrMagnitude < 0.0001f)
side = Vector3.right;
side.Normalize();
at += side * Mathf.Sin((now + stream.Seeds[i]) * 16f) * 0.015f;
stream.Drops[i].position = at;
float size = Mathf.Lerp(0.025f, 0.048f, travel);
stream.Drops[i].localScale = new Vector3(size, size, size);
}
if (landed)
SpawnPuddle(landing);
}
static Vector3 Origin(Stream stream, Vector3 aim)
{
SkopjePlayer player = stream.Player;
if (player != null && player.IsOwner && !BodyVisible(player))
{
Camera cam = null;
if (player.SkopjeFPSCamera != null)
cam = player.SkopjeFPSCamera.mainCamera;
if (cam == null)
cam = Camera.main;
if (cam != null)
return cam.transform.position + cam.transform.forward * 0.55f - cam.transform.up * 0.28f;
}
Transform hips = Hips(stream);
Vector3 at = hips != null ? hips.position : (player != null ? player.transform.position + Vector3.up * 0.85f : aim);
return at + aim * 0.16f + Vector3.down * 0.06f;
}
static Transform Hips(Stream stream)
{
if (stream.SearchedHips)
return stream.Hips;
stream.SearchedHips = true;
Transform body = Body(stream.Player);
if (body == null)
return null;
Transform[] all = body.GetComponentsInChildren<Transform>(true);
if (all == null)
return null;
for (int i = 0; i < all.Length; i++)
{
string name = all[i].name;
if (name.IndexOf("hip", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("pelvis", StringComparison.OrdinalIgnoreCase) >= 0)
{
stream.Hips = all[i];
return stream.Hips;
}
}
return null;
}
static Transform Body(SkopjePlayer player)
{
if (player == null)
return null;
if (player.ThirdPerson != null)
return player.ThirdPerson.transform;
return player.transform;
}
static bool BodyVisible(SkopjePlayer player)
{
Renderer renderer = player != null ? player.ThirdPersonRenderer : null;
return renderer != null && renderer.enabled && renderer.gameObject.activeInHierarchy;
}
static bool HitWorld(Vector3 from, Vector3 to, Transform ignore, out RaycastHit closest)
{
closest = default;
Vector3 delta = to - from;
float dist = delta.magnitude;
if (dist < 0.001f)
return false;
RaycastHit[] hits = Physics.RaycastAll(from, delta / dist, dist, Physics.DefaultRaycastLayers, QueryTriggerInteraction.Ignore);
if (hits == null || hits.Length == 0)
return false;
float best = float.MaxValue;
bool found = false;
for (int i = 0; i < hits.Length; i++)
{
Collider collider = hits[i].collider;
if (collider == null)
continue;
Transform hit = collider.transform;
if (ignore != null && (hit == ignore || hit.IsChildOf(ignore)))
continue;
if (hits[i].distance < best)
{
best = hits[i].distance;
closest = hits[i];
found = true;
}
}
return found;
}
static Vector3 Along(Vector3[] points, int count, float t)
{
if (count <= 1)
return points[0];
float total = 0f;
for (int i = 1; i < count; i++)
total += Vector3.Distance(points[i - 1], points[i]);
float want = total * Mathf.Clamp01(t);
float walked = 0f;
for (int i = 1; i < count; i++)
{
float seg = Vector3.Distance(points[i - 1], points[i]);
if (walked + seg >= want)
{
float u = seg < 0.0001f ? 0f : (want - walked) / seg;
return Vector3.Lerp(points[i - 1], points[i], u);
}
walked += seg;
}
return points[count - 1];
}
static void SpawnPuddle(RaycastHit hit)
{
EnsureArt();
if (_cube == null || _material == null)
return;
var puddle = new GameObject("PeePuddle");
var filter = puddle.AddComponent<MeshFilter>();
filter.sharedMesh = _cube;
var renderer = puddle.AddComponent<MeshRenderer>();
renderer.sharedMaterial = _material;
renderer.shadowCastingMode = ShadowCastingMode.Off;
renderer.receiveShadows = false;
Paint(renderer);
Vector3 normal = hit.normal.sqrMagnitude > 0.001f ? hit.normal : Vector3.up;
puddle.transform.position = hit.point + normal * 0.02f;
puddle.transform.rotation = Quaternion.FromToRotation(Vector3.up, normal) * Quaternion.Euler(0f, UnityEngine.Random.Range(0f, 360f), 0f);
float width = UnityEngine.Random.Range(0.16f, 0.3f);
puddle.transform.localScale = new Vector3(width, 0.012f, width * UnityEngine.Random.Range(0.75f, 1.15f));
_puddles.Add(new Puddle
{
Object = puddle,
Born = Time.unscaledTime,
Scale = puddle.transform.localScale,
});
}
static Transform MakeDrop(Transform parent, float size)
{
var drop = new GameObject("Drop");
drop.transform.SetParent(parent, false);
drop.transform.localScale = Vector3.one * size;
var filter = drop.AddComponent<MeshFilter>();
filter.sharedMesh = _sphere;
var renderer = drop.AddComponent<MeshRenderer>();
renderer.sharedMaterial = _material;
renderer.shadowCastingMode = ShadowCastingMode.Off;
renderer.receiveShadows = false;
Paint(renderer);
return drop.transform;
}
static void Paint(Renderer renderer)
{
if (renderer == null || _material == null)
return;
if (_block == null)
_block = new MaterialPropertyBlock();
_block.SetColor("_BaseColor", PeeColor);
_block.SetColor("_Color", PeeColor);
_block.SetColor("_EmissionColor", PeeColor);
renderer.SetPropertyBlock(_block);
}
static void Paint(Material material)
{
if (material == null)
return;
if (material.HasProperty("_BaseColor"))
material.SetColor("_BaseColor", PeeColor);
if (material.HasProperty("_Color"))
material.SetColor("_Color", PeeColor);
material.color = PeeColor;
if (material.HasProperty("_EmissionColor"))
{
material.EnableKeyword("_EMISSION");
material.SetColor("_EmissionColor", PeeColor * 1.4f);
}
}
static Shader YellowShader()
{
Shader shader = Shader.Find("Universal Render Pipeline/Unlit");
if (shader == null)
shader = Shader.Find("Universal Render Pipeline/Particles/Unlit");
if (shader == null)
shader = Shader.Find("Unlit/Color");
if (shader == null)
shader = Shader.Find("Sprites/Default");
return shader;
}
static void EnsureArt()
{
if (_material != null && _sphere != null && _cube != null)
return;
if (_material == null)
{
Shader shader = YellowShader();
if (shader != null)
{
_material = new Material(shader);
Paint(_material);
}
}
if (_sphere == null)
{
var temp = GameObject.CreatePrimitive(PrimitiveType.Sphere);
var filter = temp.GetComponent<MeshFilter>();
if (filter != null)
_sphere = filter.sharedMesh;
if (_material == null)
{
var renderer = temp.GetComponent<MeshRenderer>();
if (renderer != null && renderer.sharedMaterial != null)
{
_material = new Material(renderer.sharedMaterial);
Paint(_material);
}
}
UnityEngine.Object.Destroy(temp);
}
if (_cube == null)
{
var temp = GameObject.CreatePrimitive(PrimitiveType.Cube);
var filter = temp.GetComponent<MeshFilter>();
if (filter != null)
_cube = filter.sharedMesh;
UnityEngine.Object.Destroy(temp);
}
}
static void DestroyStream(Stream stream)
{
if (stream != null && stream.Root != null)
UnityEngine.Object.Destroy(stream.Root);
}
}
}
@@ -0,0 +1,23 @@
{
"runtimeTarget": {
"name": ".NETCoreApp,Version=v6.0",
"signature": ""
},
"compilationOptions": {},
"targets": {
".NETCoreApp,Version=v6.0": {
"PeePeeMod/1.0.0": {
"runtime": {
"PeePeeMod.dll": {}
}
}
}
},
"libraries": {
"PeePeeMod/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
}
}
}
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,23 @@
{
"runtimeTarget": {
"name": ".NETCoreApp,Version=v6.0",
"signature": ""
},
"compilationOptions": {},
"targets": {
".NETCoreApp,Version=v6.0": {
"PeePeeMod/1.0.0": {
"runtime": {
"PeePeeMod.dll": {}
}
}
}
},
"libraries": {
"PeePeeMod/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
}
}
}
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
@@ -0,0 +1,22 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("PeePeeMod")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+a740fec7c87ba4b24aefb7faf991fc5b69c71bd4")]
[assembly: System.Reflection.AssemblyProductAttribute("PeePeeMod")]
[assembly: System.Reflection.AssemblyTitleAttribute("PeePeeMod")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
// Generated by the MSBuild WriteCodeFragment class.
@@ -0,0 +1 @@
042143fd6e55d3b1da1d22ef48ebe9715cf4e7d7ac9bf7803b296a5ee63c4992
@@ -0,0 +1,18 @@
is_global = true
build_property.TargetFramework = net6.0
build_property.TargetFrameworkIdentifier = .NETCoreApp
build_property.TargetFrameworkVersion = v6.0
build_property.TargetPlatformMinVersion =
build_property.UsingMicrosoftNETSdkWeb =
build_property.ProjectTypeGuids =
build_property.InvariantGlobalization =
build_property.PlatformNeutralAssembly =
build_property.EnforceExtendedAnalyzerRules =
build_property.EntryPointFilePath =
build_property._SupportedPlatformList = Linux,macOS,Windows
build_property.RootNamespace = PeePeeMod
build_property.ProjectDir = C:\Users\andre\Desktop\SkopjeMods\PeePeeMod\
build_property.EnableComHosting =
build_property.EnableGeneratedComInterfaceComImportInterop =
build_property.EffectiveAnalysisLevelStyle = 6.0
build_property.EnableCodeStyleSeverity =
Binary file not shown.
@@ -0,0 +1 @@
bf5a809bc5290d85ff4eaa6eb565029fadf1e296987627646bf69f559f7d6af7
@@ -0,0 +1,12 @@
C:\Users\andre\Desktop\SkopjeMods\PeePeeMod\bin\Debug\net6.0\PeePeeMod.deps.json
C:\Users\andre\Desktop\SkopjeMods\PeePeeMod\bin\Debug\net6.0\PeePeeMod.dll
C:\Users\andre\Desktop\SkopjeMods\PeePeeMod\bin\Debug\net6.0\PeePeeMod.pdb
C:\Users\andre\Desktop\SkopjeMods\PeePeeMod\obj\Debug\net6.0\PeePeeMod.csproj.AssemblyReference.cache
C:\Users\andre\Desktop\SkopjeMods\PeePeeMod\obj\Debug\net6.0\PeePeeMod.GeneratedMSBuildEditorConfig.editorconfig
C:\Users\andre\Desktop\SkopjeMods\PeePeeMod\obj\Debug\net6.0\PeePeeMod.AssemblyInfoInputs.cache
C:\Users\andre\Desktop\SkopjeMods\PeePeeMod\obj\Debug\net6.0\PeePeeMod.AssemblyInfo.cs
C:\Users\andre\Desktop\SkopjeMods\PeePeeMod\obj\Debug\net6.0\PeePeeMod.csproj.CoreCompileInputs.cache
C:\Users\andre\Desktop\SkopjeMods\PeePeeMod\obj\Debug\net6.0\PeePeeMod.dll
C:\Users\andre\Desktop\SkopjeMods\PeePeeMod\obj\Debug\net6.0\refint\PeePeeMod.dll
C:\Users\andre\Desktop\SkopjeMods\PeePeeMod\obj\Debug\net6.0\PeePeeMod.pdb
C:\Users\andre\Desktop\SkopjeMods\PeePeeMod\obj\Debug\net6.0\ref\PeePeeMod.dll
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,85 @@
{
"format": 1,
"restore": {
"C:\\Users\\andre\\Desktop\\SkopjeMods\\PeePeeMod\\PeePeeMod.csproj": {}
},
"projects": {
"C:\\Users\\andre\\Desktop\\SkopjeMods\\PeePeeMod\\PeePeeMod.csproj": {
"version": "1.0.0",
"restore": {
"projectUniqueName": "C:\\Users\\andre\\Desktop\\SkopjeMods\\PeePeeMod\\PeePeeMod.csproj",
"projectName": "PeePeeMod",
"projectPath": "C:\\Users\\andre\\Desktop\\SkopjeMods\\PeePeeMod\\PeePeeMod.csproj",
"packagesPath": "C:\\Users\\andre\\AppData\\Local\\Temp\\cursor-sandbox-cache\\a0404811fc6e51c4c5761fd11591789f\\nuget",
"outputPath": "C:\\Users\\andre\\Desktop\\SkopjeMods\\PeePeeMod\\obj\\",
"projectStyle": "PackageReference",
"configFilePaths": [
"C:\\Users\\andre\\AppData\\Roaming\\NuGet\\NuGet.Config",
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
],
"originalTargetFrameworks": [
"net6.0"
],
"sources": {
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
"https://api.nuget.org/v3/index.json": {}
},
"frameworks": {
"net6.0": {
"framework": "net6.0",
"targetAlias": "net6.0",
"projectReferences": {}
}
},
"warningProperties": {
"warnAsError": [
"NU1605"
]
},
"restoreAuditProperties": {
"enableAudit": "true",
"auditLevel": "low",
"auditMode": "direct"
},
"SdkAnalysisLevel": "10.0.300"
},
"frameworks": {
"net6.0": {
"framework": "net6.0",
"targetAlias": "net6.0",
"imports": [
"net461",
"net462",
"net47",
"net471",
"net472",
"net48",
"net481"
],
"assetTargetFallback": true,
"warn": true,
"downloadDependencies": [
{
"name": "Microsoft.AspNetCore.App.Ref",
"version": "[6.0.36, 6.0.36]"
},
{
"name": "Microsoft.NETCore.App.Ref",
"version": "[6.0.36, 6.0.36]"
},
{
"name": "Microsoft.WindowsDesktop.App.Ref",
"version": "[6.0.36, 6.0.36]"
}
],
"frameworkReferences": {
"Microsoft.NETCore.App": {
"privateAssets": "all"
}
},
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\10.0.301\\RuntimeIdentifierGraph.json"
}
}
}
}
}
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\AppData\Local\Temp\cursor-sandbox-cache\a0404811fc6e51c4c5761fd11591789f\nuget</NuGetPackageRoot>
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\andre\AppData\Local\Temp\cursor-sandbox-cache\a0404811fc6e51c4c5761fd11591789f\nuget</NuGetPackageFolders>
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">7.0.0</NuGetToolVersion>
</PropertyGroup>
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<SourceRoot Include="C:\Users\andre\AppData\Local\Temp\cursor-sandbox-cache\a0404811fc6e51c4c5761fd11591789f\nuget\" />
</ItemGroup>
</Project>
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" />
@@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
@@ -0,0 +1,22 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("PeePeeMod")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Release")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+a740fec7c87ba4b24aefb7faf991fc5b69c71bd4")]
[assembly: System.Reflection.AssemblyProductAttribute("PeePeeMod")]
[assembly: System.Reflection.AssemblyTitleAttribute("PeePeeMod")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
// Generated by the MSBuild WriteCodeFragment class.
@@ -0,0 +1 @@
28d4c1c7ae8943c05a1dedfb4700405538fa7546a623ddf92593e82cfa96b1f7
@@ -0,0 +1,18 @@
is_global = true
build_property.TargetFramework = net6.0
build_property.TargetFrameworkIdentifier = .NETCoreApp
build_property.TargetFrameworkVersion = v6.0
build_property.TargetPlatformMinVersion =
build_property.UsingMicrosoftNETSdkWeb =
build_property.ProjectTypeGuids =
build_property.InvariantGlobalization =
build_property.PlatformNeutralAssembly =
build_property.EnforceExtendedAnalyzerRules =
build_property.EntryPointFilePath =
build_property._SupportedPlatformList = Linux,macOS,Windows
build_property.RootNamespace = PeePeeMod
build_property.ProjectDir = C:\Users\andre\Desktop\SkopjeMods\PeePeeMod\
build_property.EnableComHosting =
build_property.EnableGeneratedComInterfaceComImportInterop =
build_property.EffectiveAnalysisLevelStyle = 6.0
build_property.EnableCodeStyleSeverity =
Binary file not shown.
@@ -0,0 +1 @@
158ef05a991a20f52832317d92222c477cff0bb43c44738ef5ef154dfc745156
@@ -0,0 +1,12 @@
c:\Users\andre\Desktop\SkopjeMods\PeePeeMod\obj\Release\net6.0\PeePeeMod.csproj.AssemblyReference.cache
c:\Users\andre\Desktop\SkopjeMods\PeePeeMod\obj\Release\net6.0\PeePeeMod.GeneratedMSBuildEditorConfig.editorconfig
c:\Users\andre\Desktop\SkopjeMods\PeePeeMod\obj\Release\net6.0\PeePeeMod.AssemblyInfoInputs.cache
c:\Users\andre\Desktop\SkopjeMods\PeePeeMod\obj\Release\net6.0\PeePeeMod.AssemblyInfo.cs
c:\Users\andre\Desktop\SkopjeMods\PeePeeMod\obj\Release\net6.0\PeePeeMod.csproj.CoreCompileInputs.cache
c:\Users\andre\Desktop\SkopjeMods\PeePeeMod\bin\Release\net6.0\PeePeeMod.deps.json
c:\Users\andre\Desktop\SkopjeMods\PeePeeMod\bin\Release\net6.0\PeePeeMod.dll
c:\Users\andre\Desktop\SkopjeMods\PeePeeMod\bin\Release\net6.0\PeePeeMod.pdb
c:\Users\andre\Desktop\SkopjeMods\PeePeeMod\obj\Release\net6.0\PeePeeMod.dll
c:\Users\andre\Desktop\SkopjeMods\PeePeeMod\obj\Release\net6.0\refint\PeePeeMod.dll
c:\Users\andre\Desktop\SkopjeMods\PeePeeMod\obj\Release\net6.0\PeePeeMod.pdb
c:\Users\andre\Desktop\SkopjeMods\PeePeeMod\obj\Release\net6.0\ref\PeePeeMod.dll
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+90
View File
@@ -0,0 +1,90 @@
{
"version": 4,
"targets": {
"net6.0": {}
},
"libraries": {},
"projectFileDependencyGroups": {
"net6.0": []
},
"packageFolders": {
"C:\\Users\\andre\\AppData\\Local\\Temp\\cursor-sandbox-cache\\a0404811fc6e51c4c5761fd11591789f\\nuget": {}
},
"project": {
"version": "1.0.0",
"restore": {
"projectUniqueName": "c:\\Users\\andre\\Desktop\\SkopjeMods\\PeePeeMod\\PeePeeMod.csproj",
"projectName": "PeePeeMod",
"projectPath": "c:\\Users\\andre\\Desktop\\SkopjeMods\\PeePeeMod\\PeePeeMod.csproj",
"packagesPath": "C:\\Users\\andre\\AppData\\Local\\Temp\\cursor-sandbox-cache\\a0404811fc6e51c4c5761fd11591789f\\nuget",
"outputPath": "c:\\Users\\andre\\Desktop\\SkopjeMods\\PeePeeMod\\obj\\",
"projectStyle": "PackageReference",
"configFilePaths": [
"C:\\Users\\andre\\AppData\\Roaming\\NuGet\\NuGet.Config",
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
],
"originalTargetFrameworks": [
"net6.0"
],
"sources": {
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
"https://api.nuget.org/v3/index.json": {}
},
"frameworks": {
"net6.0": {
"framework": "net6.0",
"targetAlias": "net6.0",
"projectReferences": {}
}
},
"warningProperties": {
"warnAsError": [
"NU1605"
]
},
"restoreAuditProperties": {
"enableAudit": "true",
"auditLevel": "low",
"auditMode": "direct"
},
"SdkAnalysisLevel": "10.0.300"
},
"frameworks": {
"net6.0": {
"framework": "net6.0",
"targetAlias": "net6.0",
"imports": [
"net461",
"net462",
"net47",
"net471",
"net472",
"net48",
"net481"
],
"assetTargetFallback": true,
"warn": true,
"downloadDependencies": [
{
"name": "Microsoft.AspNetCore.App.Ref",
"version": "[6.0.36, 6.0.36]"
},
{
"name": "Microsoft.NETCore.App.Ref",
"version": "[6.0.36, 6.0.36]"
},
{
"name": "Microsoft.WindowsDesktop.App.Ref",
"version": "[6.0.36, 6.0.36]"
}
],
"frameworkReferences": {
"Microsoft.NETCore.App": {
"privateAssets": "all"
}
},
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\10.0.301\\RuntimeIdentifierGraph.json"
}
}
}
}
+12
View File
@@ -0,0 +1,12 @@
{
"version": 2,
"dgSpecHash": "KG8EvkIN5Ys=",
"success": true,
"projectFilePath": "C:\\Users\\andre\\Desktop\\SkopjeMods\\PeePeeMod\\PeePeeMod.csproj",
"expectedPackageFiles": [
"C:\\Users\\andre\\AppData\\Local\\Temp\\cursor-sandbox-cache\\a0404811fc6e51c4c5761fd11591789f\\nuget\\microsoft.netcore.app.ref\\6.0.36\\microsoft.netcore.app.ref.6.0.36.nupkg.sha512",
"C:\\Users\\andre\\AppData\\Local\\Temp\\cursor-sandbox-cache\\a0404811fc6e51c4c5761fd11591789f\\nuget\\microsoft.windowsdesktop.app.ref\\6.0.36\\microsoft.windowsdesktop.app.ref.6.0.36.nupkg.sha512",
"C:\\Users\\andre\\AppData\\Local\\Temp\\cursor-sandbox-cache\\a0404811fc6e51c4c5761fd11591789f\\nuget\\microsoft.aspnetcore.app.ref\\6.0.36\\microsoft.aspnetcore.app.ref.6.0.36.nupkg.sha512"
],
"logs": []
}