#plugins-dev-chat

1 messages · Page 24 of 1

hearty shard
#

oh

#

okay

#

i am not a fan of that

#

but oh well

celest thorn
#

Hey david i have a question regarding toys do you know why when spawning lights with just spawn message its the only toy that doesn’t work at ALL no mirror error or anything

unique crane
#

Can you elaborate

hearty shard
#

and not spawn on server

unique crane
#

Never done that

#

Sooo no clue

celest thorn
#

.

#

Here the only toy that doesn’t work its lights

unique crane
#

Or you can invert it

#

Spawn it for everyone and destroy it one players who shouldnt have it

#

That should work

restive turret
#

are you spawning as initialstate?

celest thorn
#

If you despawn them

#

And then rejoin the light becomes black

restive turret
#

After you write the SyncVar
writer.WriteVector3(this.Position);
writer.WriteQuaternion(this.Rotation);
writer.WriteVector3(this.Scale);
writer.WriteByte(this.MovementSmoothing);
writer.WriteBool(this.IsStatic);
writer.WriteFloat(this.LightIntensity);
writer.WriteFloat(this.LightRange);
writer.WriteColor(this.LightColor);
global::Mirror.GeneratedNetworkCode._Write_UnityEngine.LightShadows(writer, this.ShadowType);
writer.WriteFloat(this.ShadowStrength);
global::Mirror.GeneratedNetworkCode._Write_UnityEngine.LightType(writer, this.LightType);
global::Mirror.GeneratedNetworkCode._Write_UnityEngine.LightShape(writer, this.LightShape);
writer.WriteFloat(this.SpotAngle);
writer.WriteFloat(this.InnerSpotAngle);
writer.WriteUInt(this.ServerParentId(base.transform.parent));

unique crane
#

Well since you cause desync

#

You will have to send it again

#

Your responsible for that

celest thorn
#

Send it

#

Disconnect

#

And reconneft

#

And so it resends it

#

It bugs out

unique crane
#

How so?

celest thorn
#

Client throws an error on something

#

About a dictionary

#

And a random number

unique crane
#

???

restive turret
#

show the code for the fakelighttoy spawn

celest thorn
unique crane
#

Yeah thats gonna help me as much as not telling me about it

celest thorn
#

94 is the bytes i commented it out the part for testing other stuff

#

But this is the code i run

#

And on the bottom the client parent as 0

restive turret
#

honestly no idea

#

i dont even know what msg yo sending so cant reverse that on mirror side

upper vapor
restive turret
#

also how is your syncvar 78 or 94 ?

#

when i calculate the lighsource has 16383 as SyncVar Dirty bit

celest thorn
celest thorn
upper vapor
restive turret
#

ye but HOW

celest thorn
restive turret
#

adding all syncvar values

celest thorn
#

Oh wait no i was testing text toys

#

But yea i will try back

#

To do it with dirtysncvars

restive turret
#

tbh would be easier to edit or patch the sending method to see what basegame wants as bytes

celest thorn
#

Else i have no idea

restive turret
#

anyway the correct dirtySize is 32767 which for writing as compressedvarulong is 3952 as USHORT

#

hopefully i am right

#

if not you can hook or write the assembly to show that

celest thorn
restive turret
#

HOW

#

how do you calculate that as 94?

celest thorn
#

Tells me

#

Mirror on the error tells me

#

Missing 53

#

Bytes

restive turret
#

thats not

#

yknow i gonna edit the server mirror dll

celest thorn
restive turret
#

nvm you are right

#

but r u sure u writing 94 bytes?

celest thorn
#

No errors

#

No anything

#

Just doesn’t spawn

#

Mirror doesn’t scream at me

#

Its likely something to do on the client

#

Because similar packet works on primitives

unique crane
#

Check client log then

celest thorn
#

No errors nothing

tulip kiln
celest thorn
#

Then i crashed from my own connection that sucks

#

And rejoining i had a light that was eating other lights and the entire light system was fucked

#

Because the packet is correct and im sure about that

#

My theory is it could be checking on network spawned?

#

Because everything else works except the lights

upper vapor
celest thorn
upper vapor
#

Weird

celest thorn
#

I have an idea on how to make them work, but yea i don’t think it will work

hearty shard
#

Found no receiver for incoming ClientRpc [48108] on Respawn Effects Controller, the server and client should have the same NetworkBehaviour instances [netId=273].

#

what the flip

#

@unique crane ur like smart... right

#

help ...

#

i dont understandd :D

hearty shard
#

but

#
public static void SendFakeRpcMessage(this Player target, NetworkBehaviour behaviour, Type type, string rpcName, params object[] values)
        {
            NetworkWriterPooled writer = NetworkWriterPool.Get();

            foreach (object obj in values)
                writer.Write(obj);

            RpcMessage rpcMessage = new()
            {
                netId = behaviour.netId,
                componentIndex = behaviour.ComponentIndex,
                functionHash = (ushort)ReflectionExtensions.GetLongFuncName(type, rpcName).GetStableHashCode(),
                payload = writer.ToArraySegment(),
            };

            target.Connection.Send(rpcMessage);
            NetworkWriterPool.Return(writer);
        }
#

something here isnt right

#

48108 is the hashcode

#

wait thats not right

#

it should be -31296712

restive turret
hearty shard
#

errrr

#

so ur code isnt right

#

for getting hashcode

#

since it should be -31296712 and not 48108

#

where tf does mirror determine the hashcode

unique crane
#

Maybe its method name?

#

idk

hearty shard
#
public static string GetLongFuncName(Type type, MethodInfo method)
        {
            return $"{method.ReturnType.FullName} {type.FullName}::{method.Name}({string.Join(", ", method.GetParameters().Select(x => x.ParameterType.FullName))})";
        }
#

this is what i GetStableHashCode()

unique crane
#

I honestly do not know

hearty shard
#
private static void OnRPCMessage(RpcMessage message)
    {
      NetworkIdentity networkIdentity;
      if (!NetworkClient.spawned.TryGetValue(message.netId, out networkIdentity))
        return;
      using (NetworkReaderPooled reader = NetworkReaderPool.Get(message.payload))
        networkIdentity.HandleRemoteCall(message.componentIndex, message.functionHash, RemoteCallType.ClientRpc, (NetworkReader) reader);
    }
restive turret
#

my bad

hearty shard
#

net id is correct

restive turret
#

its ","

#

not ", "

hearty shard
#

where

restive turret
hearty shard
#

oh that part

#

yes

celest thorn
#

return $"{method.ReturnType.FullName} {type.FullName}::{method.Name}({string.Join(",", method.GetParameters().Select(x => x.ParameterType.FullName))})";

hearty shard
#

ok

#

ill tryyy

restive turret
hearty shard
#

if that is correct i will beat you

#

actually

#

i will do that anyway

restive turret
#

it works on my testing so

unique crane
hearty shard
#

errrrrr

#

well something isnt right

#

broke the doors.

restive turret
#

huh

celest thorn
#

it didn't work as expected

restive turret
#

broke deez

hearty shard
#
Disconnecting connId=0 to prevent exploits from an Exception in MessageHandler: EndOfStreamException ReadBlittable<System.UInt16> not enough data in buffer to read 2 bytes: [ @ 0/0]
  at Mirror.NetworkReader.ReadBlittable[T] () [0x00000] in <00000000000000000000000000000000>:0 
  at Mirror.NetworkReaderExtensions.ReadString (Mirror.NetworkReader reader) [0x00000] in <00000000000000000000000000000000>:0 
  at Respawning.RespawnEffectsController.InvokeUserCode_RpcCassieAnnouncement__String__Boolean__Boolean__Boolean__String (Mirror.NetworkBehaviour obj, Mirror.NetworkReader reader, Mirror.NetworkConnectionToClient senderConnection) [0x00000] in <00000000000000000000000000000000>:0 
  at Mirror.NetworkIdentity.HandleRemoteCall (System.Byte componentIndex, System.UInt16 functionHash, Mirror.RemoteCalls.RemoteCallType remoteCallType, Mirror.NetworkReader reader, Mirror.NetworkConnectionToClient senderConnection) [0x00000] in <00000000000000000000000000000000>:0 
  at Mirror.NetworkClient.OnRPCMessage (Mirror.RpcMessage message) [0x00000] in <00000000000000000000000000000000>:0 
  at Mirror.NetworkClient+<>c__DisplayClass56_0`1[T].<ReplaceHandler>b__0 (Mirror.NetworkConnection _, T value) [0x00000] in <00000000000000000000000000000000>:0 
  at Mirror.NetworkMessages+<>c__DisplayClass9_0`2[T,C].<WrapHandler>g__Wrapped|0 (C conn, T msg, System.Int32 _) [0x00000] in <00000000000000000000000000000000>:0 
  at Mirror.NetworkMessages+<>c__DisplayClass8_0`2[T,C].<WrapHandler>b__0 (Mirror.NetworkConnection conn, Mirror.NetworkReader reader, System.Int32 channelId) [0x00000] in <00000000000000000000000000000000>:0 
  at Mirror.NetworkClient.UnpackAndInvoke (Mirror.NetworkReader reader, System.Int32 channelId) [0x00000] in <00000000000000000000000000000000>:0 
  at Mirror.NetworkClient.OnTransportData (System.ArraySegment`1[T] data, System.Int32 channelId) [0x00000] in
celest thorn
#

and did work

celest thorn
hearty shard
#

errrrr

#
public static void SendFakeCassieMessage(
            this Player target,
            string message,
            bool isHeld = false,
            bool isNoisy = true,
            bool isSubtitles = true,
            string customSubtitles = "")
        {
            foreach (RespawnEffectsController allController in RespawnEffectsController.AllControllers)
            {
                SendFakeRpcMessage(target, allController, typeof(RespawnEffectsController), nameof(RespawnEffectsController.RpcCassieAnnouncement), message, isHeld, isNoisy, isSubtitles, customSubtitles);
            }
        }
#

wtf is missing

restive turret
#

are you sure u sending msg

hearty shard
#
public void RpcCassieAnnouncement(
      string words,
      bool makeHold,
      bool makeNoise,
      bool customAnnouncement,
      string customSubtitles)
    {
      NetworkWriterPooled writer = NetworkWriterPool.Get();
      writer.WriteString(words);
      writer.WriteBool(makeHold);
      writer.WriteBool(makeNoise);
      writer.WriteBool(customAnnouncement);
      writer.WriteString(customSubtitles);
      this.SendRPCInternal("System.Void Respawning.RespawnEffectsController::RpcCassieAnnouncement(System.String,System.Boolean,System.Boolean,System.Boolean,System.String)", -31296712, (NetworkWriter) writer, 0, true);
      NetworkWriterPool.Return(writer);
    }
hearty shard
#

yes

#

maybe its customsubtitles

#

cant be empty string..?

#

idk

unique crane
#

it can

hearty shard
#

yeah i checked but like

#

tf

#

what am i missing to write

restive turret
#

seems like your writing is fuckedup

unique crane
#

maybe its not arguments but something internal

hearty shard
#

also my client didnt notice the disconnect 💀

unique crane
#

Dont you need some internal id?

hearty shard
#

i dont know

unique crane
#

like netid

#

so it knows where it belongs to

hearty shard
#

i have net id

restive turret
hearty shard
#

Oh

#

[2025-05-19 14:09:55.274 +02:00] [ERROR] [LabApi] 'NullReferenceException' occured while invoking '<Enable>b__21_0' on 'SecretAPI.SecretApi+<>c': 'Object reference not set to an instance of an object.', stack trace:
at UnityEngine.Bindings.ThrowHelper.ThrowNullReferenceException (System.Object obj) [0x00018] in <6869b1608d104370ab4484f8f699b3fc>:0
at UnityEngine.Component.GetComponentFastPath (System.Type type, System.IntPtr oneFurtherThanResultValue) [0x00006] in <6869b1608d104370ab4484f8f699b3fc>:0
at UnityEngine.Component.GetComponent[T] () [0x00021] in <6869b1608d104370ab4484f8f699b3fc>:0
at Mirror.NetworkBehaviour.get_netIdentity () [0x00016] in <d73d070e2abb49cd982556c9f692e950>:0
at Mirror.NetworkBehaviour.get_netId () [0x00000] in <d73d070e2abb49cd982556c9f692e950>:0
at SecretAPI.Extensions.MirrorExtensions.SendFakeRpcMessage (LabApi.Features.Wrappers.Player target, Mirror.NetworkBehaviour behaviour, System.Type type, System.String rpcName, System.Object[] values) [0x00033] in <d15932af09ce4ad086b77f2cf4e54024>:0

#

oh.

#

that error wasnt there before

restive turret
#

skill issue

hearty shard
#
[2025-05-19 14:11:56.720 +02:00] [INFO] [SecretAPI] Hi ! Spawn wave !!!
[2025-05-19 14:11:56.736 +02:00] [INFO] [SecretAPI] False
[2025-05-19 14:11:56.753 +02:00] [INFO] [SecretAPI] True
[2025-05-19 14:11:56.769 +02:00] [INFO] [SecretAPI] True
[2025-05-19 14:11:56.784 +02:00] [INFO] [SecretAPI]
[2025-05-19 14:11:56.801 +02:00] [ERROR] [SecretAPI] Mirror.RpcMessage
[2025-05-19 14:11:56.877 +02:00] [INFO] [SecretAPI] Hi ! Spawn wave !!!
[2025-05-19 14:11:56.891 +02:00] [INFO] [SecretAPI] False
[2025-05-19 14:11:56.907 +02:00] [INFO] [SecretAPI] True
[2025-05-19 14:11:56.923 +02:00] [INFO] [SecretAPI] True
[2025-05-19 14:11:56.939 +02:00] [INFO] [SecretAPI]
[2025-05-19 14:11:56.954 +02:00] [ERROR] [SecretAPI] Mirror.RpcMessage
[2025-05-19 14:11:56.970 +02:00] EVE  (76561198397744811@steam) disconnected from IP address 127.0.0.1. Last class: Destroyed.
restive turret
hearty shard
restive turret
#

teeheeehee

hearty shard
#

i think exiled has a null check on the cassie controller

#

announcer wtv

#

idk

#

i dont wanna check exiled if thats correct

#

ill hope so

#

anyway

#

uhhh

#

i still dont know what arg im missing

restive turret
#

whats the error saying to u

hearty shard
#

Disconnecting connId=0 to prevent exploits from an Exception in MessageHandler: EndOfStreamException ReadBlittable<System.UInt16> not enough data in buffer to read 2 bytes: [ @ 0/0]

round vale
#

Is there an event to detect whenever an admin uses a command, with nwapi I used RemoteAdminCommandEvent

restive turret
hearty shard
#

i dont write the rpc message into the writer tho

restive turret
#

try doing so

hearty shard
#

wait

#

i just networkwriter .write it

#
public static void WriteString(this NetworkWriter writer, string value)
    {
      if (value == null)
      {
        writer.WriteUShort((ushort) 0);
      }
      else
      {
        int maxByteCount = writer.encoding.GetMaxByteCount(value.Length);
        writer.EnsureCapacity(writer.Position + 2 + maxByteCount);
        int bytes = writer.encoding.GetBytes(value, 0, value.Length, writer.buffer, writer.Position + 2);
        if (bytes > 65534)
          throw new IndexOutOfRangeException(string.Format("NetworkWriter.WriteString - Value too long: {0} bytes. Limit: {1} bytes", (object) bytes, (object) (ushort) 65534));
        writer.WriteUShort(checked ((ushort) (bytes + 1)));
        writer.Position += bytes;
      }
    }
#

however

#

stuff like that

#

it writes the length

#

unless i misunderstand

hearty shard
#

maybe thats the bytes im missing

#

now i just

restive turret
#

try doing what i suggested

hearty shard
#

gotta figure out how to use the correct extension for all

round vale
#

ty

hearty shard
#

i doubt itd work but ok

#

wait tf is this gonna do

#

why would i write the rpc into the networkwriter

restive turret
#

¯_(ツ)_/¯

hearty shard
#

the rpc has the writer

restive turret
#

mirror doing it too

hearty shard
#

not the other way around

restive turret
hearty shard
#

yea but

#

networkWriterPooled is never used?

#

when its written in

restive turret
#

used to write the message idk

#

mirror is strange

hearty shard
#

no its not

#

its written into it

#

then disposed

#

i think ik the issue is just

#

we need the length written to it

#

which we need networkwriterextensions

#

but i would need a switch for every single type

#

💔

#
public static void SendFakeRpcMessage(this Player target, NetworkBehaviour behaviour, Type type, string rpcName, params object[] values)
        {
            NetworkWriterPooled writer = NetworkWriterPool.Get();

            foreach (object obj in values)
                writer.Write(obj);
#

issue starts here im 99% sure

restive turret
#

try printing the position after the write

unique crane
hearty shard
# unique crane I though that WriteString() does that
public void Write<T>(T value)
    {
      Action<NetworkWriter, T> write = Writer<T>.write;
      if (write == null)
        Debug.LogError((object) string.Format("No writer found for {0}. This happens either if you are missing a NetworkWriter extension for your custom type, or if weaving failed. Try to reimport a script to weave again.", (object) typeof (T)));
      else
        write(this, value);
    }
#

this is what i call

#

Write()

#

but if the Writer<T>.write does that then why is NetworkWriterExtensions needed for mirror

#
public static string ReadString(this NetworkReader reader)
    {
      ushort num = reader.ReadUShort();
      if (num == (ushort) 0)
        return (string) null;
      ushort count = (ushort) ((uint) num - 1U);
      ArraySegment<byte> arraySegment = count <= (ushort) 65534 ? reader.ReadBytesSegment((int) count) : throw new EndOfStreamException(string.Format("NetworkReader.ReadString - Value too long: {0} bytes. Limit is: {1} bytes", (object) count, (object) (ushort) 65534));
      return reader.encoding.GetString(arraySegment.Array, arraySegment.Offset, arraySegment.Count);
    }
#

thats what client does

restive turret
hearty shard
#

also that could break basegame potentionally

#

idk

#

why am i gray

restive turret
#

muted

hearty shard
#

yk what im checking exiled

#

on wtf it does

restive turret
hearty shard
#

2 differences between me and exiled

#

exiled checks if playerr is sstill connected

#

and then has

public static ReadOnlyDictionary<Type, MethodInfo> WriterExtensions
        {
            get
            {
                if (WriterExtensionsValue.Count == 0)
                {
                    foreach (MethodInfo method in typeof(NetworkWriterExtensions).GetMethods().Where(x => !x.IsGenericMethod && x.GetCustomAttribute(typeof(ObsoleteAttribute)) == null && (x.GetParameters()?.Length == 2)))
                        WriterExtensionsValue.Add(method.GetParameters().First(x => x.ParameterType != typeof(NetworkWriter)).ParameterType, method);

                    Type fuckNorthwood = Assembly.GetAssembly(typeof(RoleTypeId)).GetType("Mirror.GeneratedNetworkCode");
                    foreach (MethodInfo method in fuckNorthwood.GetMethods().Where(x => !x.IsGenericMethod && (x.GetParameters()?.Length == 2) && (x.ReturnType == typeof(void))))
                        WriterExtensionsValue.Add(method.GetParameters().First(x => x.ParameterType != typeof(NetworkWriter)).ParameterType, method);

                    foreach (Type serializer in typeof(ServerConsole).Assembly.GetTypes().Where(x => x.Name.EndsWith("Serializer")))
                    {
                        foreach (MethodInfo method in serializer.GetMethods().Where(x => (x.ReturnType == typeof(void)) && x.Name.StartsWith("Write")))
                            WriterExtensionsValue.Add(method.GetParameters().First(x => x.ParameterType != typeof(NetworkWriter)).ParameterType, method);
                    }
                }

                return ReadOnlyWriterExtensionsValue;
            }
        }
#

💔

restive turret
#

if (target.Connection == null)
return;

hearty shard
#

thats not the issue tho rn

#

its the other difference between me and exiled

#

so i was right

terse bone
hearty shard
#

probably

terse bone
#

classic

hearty shard
#

yeah

restive turret
#

ah ye cus it prob try to ser the object

#

as a type

#

public void Write<T>(T value)

#

and when u do its Write<object>(data)

hearty shard
#

yea uh

#

also

#

yeah

#

so likeeeeee

#

💔

#

so

restive turret
#

have you ever checked your LALog?

hearty shard
#

err

#

im stupid.

#

[2025-05-19 14:11:56.802 +02:00] [ERROR] [SecretAPI] Mirror.RpcMessage
[2025-05-19 14:11:56.866 +02:00] [STDOUT] No writer found for System.Object. This happens either if you are missing a NetworkWriter extension for your custom type, or if weaving failed. Try to reimport a script to weave again.
[2025-05-19 14:11:56.867 +02:00] [STDOUT] No writer found for System.Object. This happens either if you are missing a NetworkWriter extension for your custom type, or if weaving failed. Try to reimport a script to weave again.
[2025-05-19 14:11:56.867 +02:00] [STDOUT] No writer found for System.Object. This happens either if you are missing a NetworkWriter extension for your custom type, or if weaving failed. Try to reimport a script to weave again.
[2025-05-19 14:11:56.868 +02:00] [STDOUT] No writer found for System.Object. This happens either if you are missing a NetworkWriter extension for your custom type, or if weaving failed. Try to reimport a script to weave again.
[2025-05-19 14:11:56.868 +02:00] [STDOUT] No writer found for System.Object. This happens either if you are missing a NetworkWriter extension for your custom type, or if weaving failed. Try to reimport a script to weave again.
[2025-05-19 14:11:56.877 +02:00] [INFO] [SecretAPI] Hi ! Spawn wave !!!
[2025-05-19 14:11:56.892 +02:00] [INFO] [SecretAPI] False
[2025-05-19 14:11:56.907 +02:00] [INFO] [SecretAPI] True
[2025-05-19 14:11:56.923 +02:00] [INFO] [SecretAPI] True
[2025-05-19 14:11:56.939 +02:00] [INFO] [SecretAPI]
[2025-05-19 14:11:56.954 +02:00] [ERROR] [SecretAPI] Mirror.RpcMessage
[2025-05-19 14:11:56.970 +02:00] EVE (76561198397744811@steam) disconnect

#

😭

#

yeah

#

so its cuz its object

#

wtf do i do

#

@thin shuttle do u think i can still exiled mirror extension

#

well

#

specifically i wanna steal the static dictionaries

#

public static ReadOnlyDictionary<Type, MethodInfo> WriterExtensions

#

or is there another way to do this hmm

restive turret
#

yes

#
 NetworkWriterPooled networkWriterPooled = NetworkWriterPool.Get();
 foreach (object obj in objects)
 {
     var GenericType = typeof(Writer<>).MakeGenericType(obj.GetType());
     var writer = Activator.CreateInstance(GenericType);
     var writeAction = writer.GetType().GetEvent("write");
     if (writeAction == null)
     {
         CL.Warn($"Tried to write type: {obj.GetType()} but has no NetworkWriter!");
         return;
     }
     writeAction.RaiseMethod.Invoke(writer, [networkWriterPooled, obj]);
 }
 player.Connection.Send(new RpcMessage()
 {
     netId = networkBehaviour.netId,
     componentIndex = networkBehaviour.ComponentIndex,
     functionHash = (ushort)functionHash,
     payload = networkWriterPooled.ToArraySegment()
 });
 NetworkWriterPool.Return(networkWriterPooled);
#

try this

hearty shard
#

[2025-05-19 14:48:32.267 +02:00] [ERROR] [LabApi] 'MissingMethodException' occured while invoking '<Enable>b__21_0' on 'SecretAPI.SecretApi+<>c': 'Default constructor not found for type Mirror.Writer`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]', stack trace:

#

its static

#

might have it

#

IT WORKS

#

@restive turret i love you

#

/p

restive turret
#

oh it doesnt need the writer there

#

am i right?

hearty shard
#
Type genericType = typeof(Writer<>).MakeGenericType(obj.GetType());
            FieldInfo? writeField = genericType.GetField("write", BindingFlags.Static | BindingFlags.Public);
            if (writeField == null)
            {
                Logger.Warn($"Tried to write type: {obj.GetType()} but has no NetworkWriter!");
                return;
            }

            object? writeDelegate = writeField.GetValue(null);
            if (writeDelegate is Delegate del)
            {
                del.DynamicInvoke(writer, obj);
            }
            else
            {
                Logger.Warn($"Writer<{obj.GetType()}>.write is not a delegate!");
            }
round vale
#

using LabApi.Loader.Features.Plugins;
using LabApi.Events.Handlers;
using System;
using System.Net.Http;
using System.Text;
using LabApi.Events.Arguments.ServerEvents;

namespace Plugins
{
public class AdminWebhookPlugin : Plugin
{
private static readonly HttpClient httpClient = new HttpClient();
private const string WebhookUrl = "";

    public override string Name => "Admin Webhook Plugin";
    public override string Author => "BorkoAXT";
    public override string Description => "Logs admin commands to Discord webhook";
    public override Version Version => new Version(0, 0, 1, 0);
    public override Version RequiredApiVersion => new Version(3, 0, 0);

    public override void Enable()
    {
        ServerEvents.CommandExecuted += OnPlayerCommand;
    }

    public override void Disable()
    {
        ServerEvents.CommandExecuted -= OnPlayerCommand;
    }

    private void OnPlayerCommand(CommandExecutedEventArgs ev)
    {


        var adminName = ev.Sender.Nickname;
        var command = ev.CommandName;
        var time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");

        var message = $"**Admin command Used**\n👤 **By:** {adminName}\n🔨 **Command:** `{command}`\n⌚ **At:** {time}";

        var payload = new
        {
            content = message
        };

        var json = Newtonsoft.Json.JsonConvert.SerializeObject(payload);
        var content = new StringContent(json, Encoding.UTF8, "application/json");

        _ = httpClient.PostAsync(WebhookUrl, content);
    }
}

}

can anyone tell me why this might not work. I tried it and nothing happened but I can't really tell what's wrong

hearty shard
#

I LOVE MIRROR

#

MIRROR IS AMAZING

#

this definitely wasnt me for the past day

celest thorn
celest thorn
#

you are hating on the best lib ever for networking

hearty shard
#

i hate YOU

#

mirror is lovely

#

i love mirror!!!

#

i dont hate it!!

celest thorn
obtuse spruce
#

LabAPI register commands before loading Config ?

obtuse spruce
#

💀

restive turret
#

we have a small bug

#

even when setting PlayerUnlockingGeneratorEventArgs.IsAllowed = true it doesnt unlock

hearty shard
#

@obtuse spruce use labapi issues tabn

restive turret
#

This:

if (!playerUnlockingGeneratorEventArgs.IsAllowed)
{
  flag = false;
}

Should be:

flag = playerUnlockingGeneratorEventArgs.IsAllowed;
obtuse spruce
thin shuttle
royal mica
restive turret
#

idk but there should be the ShouldUnlock or smth

royal mica
#

Seems like a blocking pattern

restive turret
#

like in normal door

#

CanOpen or like that

royal mica
#

Why is another EventHandler currently blocking the event?

restive turret
#

what

royal mica
#

OOh I know what you want to do, you want a player to be able to open the generator without the correct keycard?

restive turret
#

yes

#

but since no CanOpen i had to improvise

hearty shard
#

in my own project

#

well except the mirror stuff

#

i just wanted to try it

#

idk if ill even merge it

royal mica
#

Since I see events as "if any blocks, then don't do event" pipeline (managing every change state at once would be nightmare) you could just open it manually when event fires

restive turret
#

ye i do that

#

but ye when someone blocks it others can unlock it

obtuse spruce
restive turret
#

fixed in 14.2

hearty shard
#

actually

#

what in sl uses rpc

#

other than set parent on admin toys and cassie

#

i cannot remember anything else

restive turret
obtuse spruce
#

SL have add set parent ????

hearty shard
#

on admin toys

hearty shard
obtuse spruce
#

lmao mirror handle it perfectly ?

hearty shard
#

it has nothing to do with mirror

restive turret
#

it has

#

since its networked

hearty shard
#

you tell game
"pls make this parent"
then it sends it along side a net id

restive turret
#

silly goose

hearty shard
#

mirror sends the msg

#

yes

#

but if it cant do that the game wouldnt work at all

hearty shard
celest thorn
hearty shard
#

might be wrong

#

this maybe

celest thorn
restive turret
#

ye its EntityStateMessage

#

using SerializeClient

hearty shard
#

im so smart

celest thorn
#

its so stupid

restive turret
#

nvm idk

hearty shard
#

it is

#

Dirty bits is syncvar stuff

#

idk how it works tho

celest thorn
#

it actually is

#

lol

#

ok i will shut up

hearty shard
#

what the fuck

#

😭

#

im so glad i only did mirror once

#

never again

tough ivy
#

How cute u r

hearty shard
plain gazelle
#

How can i use Labapi to send a player a console and a RA-console message?

hearty shard
plain gazelle
#

Thanks, and that is just the regular console iirc right?
Is there something for the RA-console?

hearty shard
plain gazelle
#

o.o
Thanks ^^"

wispy dirge
#

is there a way to switch off a radio?

#

im tryna make like a powercut event and it makes radios not work or smthn

teal junco
#

I think so, but it doesnt sync to the client very well

devout terrace
#
    public static IEnumerator<float> PlayMusic(string filepath)
    {
            var speaker = SpeakerToy.Create();
            using var vorbis = new VorbisReader(filepath);
            var channels = vorbis.Channels;
            var samples = new float[vorbis.TotalSamples * channels];
            List<float> final = new List<float>();
            while(vorbis.ReadSamples(samples, 0, samples.Length) > 0)
            {
                for (int i = 0; i < samples.Length; i++)
                {
                    final.Add(samples[i]);
                }
                yield return Timing.WaitForOneFrame;
            }
            speaker.Play(final.ToArray());
    }```
#

i have no ideaClassDSadge

worthy rune
teal junco
devout terrace
#

i got it

upper vapor
teal junco
#

Oh okay

upper vapor
#

i don't like it though cuz you have to allocate arrays every time you wanna queue a "clip"

#

for those who are reading entire songs into memory:
what is wrong with you ClassD_Hollow

royal mica
#

ok very strange.
If I disable the collision on a Primitive, the client instantly disconnects

upper vapor
#

what

royal mica
#

Yeah

upper vapor
#

like

royal mica
#
            if (!collidable) {
                Collider? spawnedCollider = AccessTools.Field(typeof(AdminToys.PrimitiveObjectToy), "_collider").GetValue(spawned) as Collider;
                if (spawnedCollider == null) {
                    Log.Error("Failed to get toy collider");
                }
                else {
                    spawnedCollider!.enabled = false;
                }
                //spawned.Flags = PrimitiveFlags.Visible;
            }

This kills the client

upper vapor
#

primitive.Flags &= ~PrimitiveFlags.Collidable

royal mica
teal junco
upper vapor
#

check how i did it in sloc

#

it works for me

royal mica
upper vapor
#

you can also use the plugin toomuchtrolling

upper vapor
#

.ogg limitation is kinda sad
the users have to convert their file not only to ogg but to 48000Hz mono

teal junco
upper vapor
#

new float[reader.TotalSamples * channels]

teal junco
upper vapor
#

i wanna create an audio player api that is more developer-friendly

#

and doesn't allocate megabytes of RAM

teal junco
#

how should a really long file be read then

upper vapor
#

technically you can load any amount of audio until you get an OOM toomuchtrolling

teal junco
upper vapor
#

yep

teal junco
#

i assume its possible though

#

idk how buffers and streams and stuff work though

#

i would do it if i could

upper vapor
#

it's not that difficult but it has some caveats

worthy rune
upper vapor
#

which is not ideal

#

the developer would have to reuse arrays somehow but it's not easy to tell when a clip has been played

royal mica
# upper vapor what

Found out why. Anti exploit disconnects you if any player action causes an exception

upper vapor
#

yea

#

where was the exception

royal mica
#

At the body of the function, cause I do not have 0Harmony.dll icant

#

AccessTools is from harmony

upper vapor
#

yyyyeaaaaa

static meteor
#

Install the harmonylib nuget reference if you need harmony

worthy rune
upper vapor
#

i just *= 5

worthy rune
#

should be

#

it might break if your buffer time is really small like 10ms

upper vapor
#

the transmitter runs in a coroutine sooooo
when do you invoke play for it
whenever there's less than n clips?

royal mica
upper vapor
#

yeah i would like to have a small buffer to avoid allocations pretty much completely

#

instead of shuffling through a pool of arrays

royal mica
#

ok very strange. isTrigger still doesn't work. Still collidable

#

I do not get it. This worked before

upper vapor
#

this is a bit weird

#

and the transmit coroutine doesn't get killed when the speaker is destroyed

#

is that intentional?

worthy rune
upper vapor
#

yeah but you could use Player.AuthenticatedList

#

instead of an unverified check and dictionary lookups

#

do i make a PR

worthy rune
# upper vapor is that intentional?

transmitters are separate from the speaker toys themselves, but yeah if all toys with controllerId matching the transmitter are destroyed then we could probably stop the playback on all transmitters targetting that id

worthy rune
upper vapor
#

aight makes sense

upper vapor
#

-# i'm lazy

worthy rune
upper vapor
#

indeed

#

oh wait i should probably benchmark it first

buoyant oyster
#

does round start trigger PlayerChangeRoleEvent?

upper vapor
#

it should with the spawn reason RoundStart

unique crane
#

^

buoyant oyster
#

also what are the events to check when damage are dealt to players, whether that be humans or scps?

upper vapor
#

PlayerHurtingEvent iirc

#

PlayerHurt if you want the one after taking damage

buoyant oyster
#

getting super confused by these names

#

ty

#

im spoiled by javadocs pain

upper vapor
unique crane
buoyant oyster
#

just a lot to tackle without a documentation page not you guys' fault

unique crane
#

Ah

#

I would like to expand the wiki page for stuff like this

buoyant oyster
#

u know what javadoc sites look like right

#

something like that would be super helpful

upper vapor
#

like an api reference, yeah

#

probably wouldn't be that difficult to auto-generate it but ehh

#

do you use NuGet?
then you have doc access in your IDE and you can navigate fairly easily

unique crane
#

Oh wait its like that big UI window

#

AAAH

#

I know

buoyant oyster
#

coming from java with intellij

upper vapor
upper vapor
#

should work if you installed the LabApi reference through NuGet

buoyant oyster
#

ive never had to use the quick documentation in intellij...

upper vapor
#

did you

#

did you go to the web-based api reference every time?

#

😭

buoyant oyster
#

i just had it on a second monitor leave me be

upper vapor
#

interesting choice

#

this thing is pretty useful

#

also you can use "go to definition" to decompile classes

#

which should contain docs if applicable

royal mica
#

i hate javadoc

#

inline documentation and go to definition is much better IMO

carmine prawn
#

Can I hot-reload plugin.dll?

#

wait for server soft restart always long

upper vapor
#

good luck lol

#

there isn't a built-in way

#

and there may not be a way at all

terse bone
#

you can't unload assembly from appdomain so good luck

carmine prawn
slate flume
restive turret
#

F

thin shuttle
#

@unique crane i need explanation of why this has been separated in two event ?

#

what the purpose ?

#

why not just making one event

slate flume
#

Because the Tesla idles before going off

#

It activates when you're in the room, but doesn't fire until you're in proximity

#

That's why it's two separate events

thin shuttle
#

just make property going on and off depending of your proximity

#

(by default if it's in range of Idling it's trigger the event)

#

so the property "IsInIdleRange" is true by default

#

(ev.DisableTesla is an Exiled thing)

#

but other than that it's would have been easier to make it in a single event

grand flower
hearty shard
grand flower
#

oh

#

nvm then

#

forgot about exiled

hearty shard
#

Yeah

thin shuttle
#

yeah

#

no worry

#

i just need to know why NW wanted to put 2 event instead of one that handle both Idling Triggering

buoyant oyster
#

Do PlayerLeftEvent and PlayerKickedEvent both trigger when someone is kicked or banned?

thin shuttle
#

because mostly with how nw did make it you will need to register two event to disable a tesla for a player

thin shuttle
worthy rune
#

not sure who made that event, but we could always change it

buoyant oyster
#

i need an event that broadly covers every situation a player could disconnect from the server if thats a thing

#

i have no idea what that would be

thin shuttle
thin shuttle
#

to this

thin shuttle
# worthy rune it should

also instead of giving only 1 ReferenceHub as who trigger the tesla give all the player who could have trigger the tesla

#

(or just don't say who trigger the tesla)

#

because that would depends on where is Player in Player.List

#

and for plugin feature is kinda suck / unfair for player

worthy rune
#

i see

thin shuttle
#

for example if you give a penality to player that make tesla trigger then you can only put it to the player that is in the area & is the higher in Player.List

worthy rune
#

can you make an issue on the labapi github for it

thin shuttle
#

i will let you make the suggestion for me it's everything i have to said here

buoyant oyster
#

erm (in PlayerChangedRoleEventArgs)

thin shuttle
#

not really have time rn

slate flume
thin shuttle
#

i am handling Exiled Issue rn

slate flume
#

Just makes it easier to handle outside cases

#

A lot of them CAN be condensed but like why

thin shuttle
#

is not after the event pass

#

Flipping & Flipped is fair

#

because something changed

thin shuttle
#

between this two state

slate flume
#

I would imagine they would activate different depending on proximity to tesla gate

thin shuttle
#

between PlayerIdling and PlayerTriggering nothing happnened between this two so no reason to separated them

slate flume
#

Did you judge it based on walking into the tesla room or spawning in the tesla room?

#

Like were you intentionally triggering both?

#

Idling and Triggering should activate at different times based on proximity

thin shuttle
#

between this two event code do nothing other than check

#

and do not affect TeslaGate state

#

PlayerTriggering & PlayerTriggered something happenened between this two so that a good event

slate flume
#

This is generally my understandng of how idling vs triggering should be

thin shuttle
slate flume
#

Wdym?

thin shuttle
slate flume
#

Yeah cause it's just basic distance but I was too lazy to draw big circles

thin shuttle
slate flume
#

I feel like I'm completely missing your point

worthy rune
slate flume
#

I don't see what the issue is with this

#

They're two separate things
Idling and triggering can happen at the same time, but they can also happen separately

thin shuttle
thin shuttle
thin shuttle
thin shuttle
slate flume
#

You could say the same thing with other events like Scp173 Creating Tantrum and SCP173 Created Tantrum but for niche outside cases in plugins the distinction can be useful

thin shuttle
#

there for real only packet sent to Client

#

at this moment

thin shuttle
slate flume
thin shuttle
#

anyways i thinks Ritide got what i means and why it's actually useless for having two event instead of one

#

(because nothing happenned between this two action)

slate flume
thin shuttle
#

no nothing

slate flume
#

Idle can trigger without triggering Triggering

thin shuttle
#

yeah that can be done on Exiled too

#

and there only one event

slate flume
#

Triggering = Idling, Idling =/= Triggiering

thin shuttle
#

i know

slate flume
#

So something can happen between Idle and Trigger

#

^^

thin shuttle
#

that why they are different propperty

thin shuttle
#

on client only

#

you only send packet to client

#

that tesla get idle/ triggering

slate flume
#

I'm confused as to why you say they happen at the same time, because you can trigger Idling separately from Trigger, meaning they can happen at different times

thin shuttle
#

the update in code

#

that why i told you to not think as distance

#

that not the important part

#

for making event

still thistle
#

I NEED EXILED 14.1

thin shuttle
#

just install it ?

slate flume
still thistle
#

NOT HAVE IT

thin shuttle
#

that good

still thistle
#

Wait what ADDED

thin shuttle
#

on Tesla there two event before and two event after

still thistle
#

YAY

slate flume
thin shuttle
#

while they could be combine in one event before and one after

thin shuttle
#

just give false if player is too far to trigger Triggering and enough near to respond true if in idle

slate flume
thin shuttle
#

yeah

thin shuttle
#

you don't need 2 event

#

for something happening at same time

#

you only need to give both information and both action possibility to it

slate flume
thin shuttle
#

they do

slate flume
#

You can Idle without Triggering, by definition meaning they don't happen at the same time

#

If one event can trigger without the other, then it merits having its own event

thin shuttle
#

you have the same ability with 1 TriggeringTesla event from

than both event from LabAPI

#

exiled one is not more restrictive because of being united

slate flume
#

Yes you could have a boolean stating whether or not you're triggering, and merge it into one event, but you can do that with a lot of other events too

#

The point in the way they do it is to make it straight-forward and easy for people to handle it

thin shuttle
#

while for exiled you only need to register one

slate flume
upper vapor
#

i'm with yamato on this one

restive turret
#

have 2 arg?

thin shuttle
#

other one will still trigger

slate flume
#

Yes I know

#

Your point is that if people want to handle it separately, they can just use an if statement to check which it is

thin shuttle
#

What about people who want it to be able to idle without triggering?
simple

ev.IsTriggerable = false

slate flume
#

My point is that you can just keep it separate

thin shuttle
#

ev.IsTriggerable = false;
or
ev.IsInIdleRange = false;

slate flume
#

I'm not saying you CAN'T do it your way

#

I'm saying that the way it is currently is fine

restive turret
#

me when i quit sl

thin shuttle
slate flume
thin shuttle
#

dev purpose is also to simplify code to the maximum

restive turret
#

there is no simplifying

thin shuttle
#

when you remove an event is simpliying this

#

to that

slate flume
thin shuttle
slate flume
#

I understand your point, just I disagree

thin shuttle
#

i fully disagreed with overcomplicated code

#

so it's fine

#

:)

#

sure it's work by making more event

slate flume
#

Two events isn't overcomplicated, it's just separating workload, but ig that's just difference in opinion

#

You could argue it's more work to separate events into things like Lunging vs Lunged or Creating vs Created and go through the exact same debate

thin shuttle
slate flume
#

Exactly

thin shuttle
#

more work but not useless

#

so not overcomplicated

slate flume
#

My point is that the argument you'd make for something like that is almost the exact same as the argument you're making now for condensing these events

thin shuttle
#

no it's not the same

slate flume
#

Because you can just use an if statement to distinguish between the two and handle them separately

thin shuttle
#

like i said the difference between what you said and what i said it's what happen in between

#

Triggering and Idling have nothing between this two

slate flume
#

The thing is Creating vs Created can happen at the same time

#

They can also happen at different times depending on the event

#

Same thing with tesla gate

thin shuttle
#

Creating
Created have an action going one in between

slate flume
thin shuttle
#

you wouldn't have an event if there no action

#

because no purpose

slate flume
#

Sometimes the Creating event is just used to allow someone to cancel it before created

thin shuttle
#

yeah you explain the puprose your self here

#

there nothing of that with tesla

slate flume
#

Except there is

#

The triggering event being separate allows you to cancel someone triggering it without cancelling idling

thin shuttle
thin shuttle
#

anyways i need to continue fix for exiled

slate flume
#

You CAN condense it

thin shuttle
#

i need to go

slate flume
#

Doesn't mean you should

upper vapor
#

compared to 2

thin shuttle
#

i also see no benefit in having it twice

#

anyways now i fix LabAPI tesla Event on Exiled

restive turret
#

There is many places where some more parameters would benefit much

buoyant oyster
#

can yall implement getters and setters for things like this

#

like i know why OldRole doesnt have a setter but why doesnt NewRole have either

buoyant oyster
#

PlayerChangedRoleEvent

hearty shard
#

Use Changing

#

The players role has already been changed in the event ur using

#

Thus theres no cancelling or modifying it

#

Only the result

buoyant oyster
#

i dont need to modify them, just some consistency would be nice

hearty shard
#

That is consistent tho?

hearty shard
#

@buoyant oyster Okay so

Role change is requested
ChangingRole is called with the proper stuff
Based on that, role will be changed
Then ChangedRole will be called with the result

#

Hurting is before Hurt
You cannot modify Hurt because the damage has already been done in Hurting

buoyant oyster
#

i know how this works, thats not what i mean

#

its a small nitpick anyway its whatever

hearty shard
#

Ur asking for a setter that shouldnt be there though

buoyant oyster
hearty shard
#

Yes getters for Team

#

NewRole has it because its PlayerRoleBase

#

OldRole is stored as RoleTypeId because it will be pooled

buoyant oyster
#

ah

slate flume
#

Ughh I need to publicize mirror?

hearty shard
slate flume
#

Player scale

#

I need SendSpawnMessage

hearty shard
#

Errrrr

#

You can publicize really easily
Or use reflection for it

slate flume
#

I'm just publicizing

hearty shard
#

Use the uhh

#

Bepinex publicizers

slate flume
#

I use BepInEx

hearty shard
#

Yeah

slate flume
#

Yeah

#

I publicize the Assembly whenever I do a plugin anyways

hearty shard
#

Ya

slate flume
#

It just means another step to do every update lmao

#

Wait quick question

#

When I change a player's scale, will it update automatically for new people joining, or will I have to send them the message as well?

slate flume
#

Dope

hearty shard
#

Unless ur trying to fake a scale

#

But yes it should work fine if ur just doing normal scale

slate flume
#

Nah I'm changing the local scale and then updating it

hearty shard
#

Yeah

#

Same as exiled, same as me

#

Should do the job

restive turret
#

Yup

#

Changing appearance is different tho

slate flume
#

So you have to update it for every new join

restive turret
#

And every player role change

slate flume
#

That's why the superior way to do CISpy is to not fuck with appearance lmao

#

Just work with the damage handling

restive turret
#

I did pretty much that already

#

I meant the sync of appearance

#

Works great on testing

slate flume
#

On the server I do dev stuff for we used to do CISpy with disguise and people kept noticing inconsitencies in the disguise somehow and were able to figure out who it was

#

Apparently faking the connection wasn't full-proof or something idk

#

I only recently started doing dev stuff and I'm completely remaking everything so it'll be different

restive turret
#

I can always fasten the Coroutine to sync faster

slate flume
#

I think the problem was just that there's slight differences between the team models for different classes so the game would freak out with a couple niche cases

restive turret
#

Worked with faking spcs too

hearty shard
#

Slejm...

slate flume
#

Yeah I'm just not gonna fuck with it

restive turret
#

Ye

#

Its 00:10 what u want eve

restive turret
#

@hearty shard whatthehecc thegoat

slate flume
#

If I do CISpy stuff I can just fuck with damage handler stuff instead

restive turret
#

Ye , I dont really wanna fk damage handler

slate flume
#

Fair

restive turret
#

I already doing it with custom damaging

#

I think it doesn't even trigger it if its on same team

hearty shard
#

errr

#

yeah idk

restive turret
#

Go to sleep

#

Or i will eat u

hearty shard
#

Uh

hearty shard
restive turret
#

A well done eve steakSCP4796Pineapple

buoyant oyster
#

easy way to grab the zombie count that displays in the upper right of the screen as 049?

slate flume
#

[ERROR] [LabApi] 'MethodAccessException' occured while invoking 'OnPlayerFlippedCoin' on 'SodaPlugin.CoinEventHandler': 'Method Mirror.NetworkServer.SendSpawnMessage(Mirror.NetworkIdentity,Mirror.NetworkConnection)' is inaccessible from method SodaPlugin.SizeHandler.ChangePlayerSize(LabApi.Features.Wrappers.Player,UnityEngine.Vector3)''

#

Motherfucker

#

I publicized mirror and tried to use SendSpawnMessage

#

And it didn't work

worthy rune
#

did you enable unsafe code

slate flume
#

OH I'm just stupid

#

My bad

#

Homeslice

#

I did that on every other repo hubert_facepalm

worthy rune
#

we have all been there

hearty shard
#

hi riptide

#

Miss me?

worthy rune
#

no

hearty shard
#

Whys everyone so mean

slate flume
#

I apologize on their behalf

grand flower
#

Anyone ever get a bug where a player's set to 0 hp, is a "spectator" but stays in the world

#

like they're still alive but also they're not

hearty shard
#

I dont remember the cause

#

Havent seen that issue since like a year ago xd

grand flower
#

we're having this happen again and again

#

i think I managed to reduce it but it's like

#

wtf

soft depot
#

does anyone have a specific number for the players FOV? I needs it for math

grand flower
#

can the server change the accuracy of a weapon for the player

grand flower
#

ah through an effect

#

cool

acoustic cosmos
#

Is it just me or PlayerEscapingEvent is not called in 14.1

#

Probably just me

#

Yeah it was me

slate flume
#

I genuinely have no clue what to do lmao

#

How the fuck am I supposed to do SSSS

#

Pardon my french

slate flume
#

Am I that stupid hubert_facepalm it's all coming together

#

I just had to look at it like this:
Generally the majority of use cases will be made more convenient by combining rather than splitting

#

Even if it "follows the general pattern" or it makes sense on a surface level to split a lot of these up, you have to ask what's more convenient for a majority of people using it

grand flower
#

Does LabAPI have a wrapper to spawn a live grenade

restive turret
#

Kind of

grand flower
#

TimedGrenadeProjectile.SpawnActive?

restive turret
#

Ye

#

The last value is the fuse time

upper vapor
restive turret
unique crane
grand flower
#

little suggestion but would it be possible to add a damage multiplier parameter to the method?

restive turret
#

Damage is based on a curve

grand flower
#

ik

#

had to make my own way of modifying the curve by applying the multiplier to it

#

just figured it'd be cool as a simple parameter

restive turret
#

I think there is float for that ain't?

#

In basegame

grand flower
#

if there is do tell :O

unique crane
#

No there isnt

#

Only for SCPs

restive turret
#

Oh yeah

unique crane
grand flower
#

yeeee

#

that's why i went the curve way

restive turret
#

Y'know what would be fun

grand flower
#

which isn't toooo hard but it's a little bit of a setup

restive turret
#

Getting the xml of the game too SteamHappy

#

Tbh i found the curve thing but no idea about it's values

grand flower
#

time is distance

#

value is damage

upper vapor
#

Isn't the default curve in the explosion settings

grand flower
#

heads up: don't make the mistake of modifying the curve in the grenade prefab

#

don't ask how I found out

upper vapor
#

Maybe that isn't ideal

grand flower
#

yeah no took me a while to figure out how players were reporting SCPs dying from 5 meters away to one nade, pink candy or jailbird

restive turret
#

I think that's a lot

grand flower
#

yeah

royal mica
#

that sounds fun

grand flower
#

yeaaah no

#

lost my sanity chasing that one

#

almost started thinking we had an outdated patch corrupting IL or something

chilly verge
#

How would I check if a Keycard fullfill a set of permissions?

grand flower
#

but the whole "bug would keep happening until a server restart" ended up pointing me towards that direction

upper vapor
#

Something like this

#

Or check the details

unique crane
#

I should do something like that base labapi

royal mica
#

oohh imagine if you could introduce custom permissions for keycard for more advanced handling

restive turret
#

Also dont forget to NOT inlcude single use keycard

#

If u dont clamp the value you can maybe create a 5,5,5 kc

#

Tbh no idea if that even would work

royal mica
#

I meant like you could create a whole new perm group

restive turret
#

Patch the enum

royal mica
#

The client won't see it :\

restive turret
royal mica
#

Also easier to create a custom item wrapper and just handle attributes separately if you want to do it currently, but in the future where more "modding" rather than "plugin" approach exists it would be nice

#

if we get "modding" approach at all

#

SCP:SL surf servers Stronge

restive turret
#

Also an I the only one or when blackout you don't see anything we scp like prev?

upper vapor
royal mica
restive turret
#

Funny af and broken

royal mica
upper vapor
#

Bruh

#

Peak SL experience

terse bone
upper vapor
restive turret
#

Well you get it basegame

random scaffold
#

how i can change damage in OnPlayerHurting?

thin shuttle
upper vapor
random scaffold
#

Why not just hand it over right away?

upper vapor
#

Make a PR if it's that annoying shrug

random scaffold
hearty shard
random scaffold
hearty shard
random scaffold
hearty shard
#

You just gotta

Amount
get => damage is Standard standard ? standard.Damage : 0
set
{
if damage is Standard thing
thing.Amount = 5;
}

#

written on mobile

#

but yeah its smth along those lines

random scaffold
#

then how

hearty shard
#

shrug

#

publicize

#

idk why its internal

upper vapor
#

Though it's irrelevant in the PR's context

random scaffold
restive turret
#

Tick enable unsafe code

unique crane
upper vapor
#

New devs

random scaffold
#

lol

unique crane
#

In terms of modding, it is

#

and if you wanna do c++ in c#

random scaffold
#

not third party

upper vapor
unique crane
#

^

upper vapor
#

(^ Not in framework 4.8 lol)

#

Even strings have unsafe code in them

#

Would you rather use reflection every time or tick a box once when setting up the project

#

I used to do reflection a lot but when I realized that publicizing exists:

unique crane
#

Poor ced

random scaffold
upper vapor
#

Transpiler testing toomuchtrolling

random scaffold
#

both will be called if is cheater?

upper vapor
#

Decompile and check

#

I'd assume they're separate

restive turret
#

finally now I played SL more than R6S

royal mica
hearty shard
hearty shard
royal mica
#

Interesting

brisk matrix
#

Wat 😭

random scaffold
#

when player using painkillers

#

which effect it given?

hearty shard
#

no effect

#

just a healing

chilly verge
#

What event is dispatched when I interact the the small chamber where the SCPs are in? e.g. 018, etc