#plugins-dev-chat

1 messages · Page 45 of 1

restive turret
#

I can open them by code not really care about it, the thing is.
Cant really detect if its a door, or dont know how to detect

grand flower
#

Just raycast

restive turret
#

How i never used it

grand flower
#

Check what mask player interactions use

#

Raycast from the player's camera position, in the direction they're facing

#

(add like, 10/20cm away from the camera position to avoid hitting the head)

#

Raycast using the interaction distance

#

If you hit something, check the components for a door variant

restive turret
#

Oh components i totally forgot that

soft turtle
#

Is there any event where I can get the User Id of the player when he leaves the server?
When LabApi.Events.Handlers.PlayerEvents.Left is called the UserId of the player is already null

grand flower
#

It shouldn't be

#

If it is, check when the player changes roles to Destroyed

icy knoll
#

if that exists

grand flower
#

It doesn't because you cant stop a user from leaving

restive turret
#

That would be funny

#

Ngl

grand flower
#

alt f4 be like

worthy rune
grand flower
#

Not null for us

worthy rune
#

yeah i would have alot of problems if thats true

worthy rune
soft turtle
soft turtle
#

LabApi.Events

#

Not Exiled

grand flower
#

Is PlayedTime null

worthy rune
soft turtle
grand flower
#

Fair

soft turtle
worthy rune
#

try without it installed

soft turtle
#

Ok thx

grand flower
#

Wait do devs really try to use both at the same time

#

Sounds like a recipe for disaster

restive turret
worthy rune
#

well, exiled is a labapi plugin so there isnt away to avoid it

#

thats just how it is

restive turret
#

Exiled slowly begin to be much headache for me

grand flower
#

Idk we just use labapi and then patch whatever we need that it doesn't give us

#

Using both would be suicide imo

restive turret
#

I had to make my own "ExiledFixer" plugin

worthy rune
#

also this goes for any plugin with alot of patches, im not singling exiled out its just the most popular and has the most patches

#

next would be cedmod

grand flower
#

All of our plugins are handmade for that reason

#

If something breaks we know it's on us

pine parcel
#

are there any good docs anywhere for LabAPI, or is it a case of look into other projects to figure out people have solved certain issues?

grand flower
#

Or well, Northwood

restive turret
grand flower
#

something something 079

#

inb4 "not a priority"

restive turret
#

Our scale broke bc i tried to use the Player:Scale and then respawning the player

grand flower
#

Oh we're currently missing a few features because of player scaling

restive turret
#

Was funny

upper vapor
restive turret
#

Happened while I was sleeping

grand flower
#

I fixed it, and then a few days later it broke again

#

Servers just instant dying

#

No logs

grand flower
#

So now we're at a point where 14.1.1's scaling is actually worse than manual scaling in 14.1 and older

restive turret
#

Ye even if I set my scale in midgame somehow it gives me +30 ms

#

Older isn't

grand flower
#

I wish we could revert it but nope

#

Idk I only started working on SL stuff during the 14.1 beta

worthy rune
#

yeah thats unfortunate

restive turret
#

Plz riptide fix

grand flower
#

Sucks because we used it for a good amount of things

#

But the instant crashes that take down 2 servers are a no no

restive turret
#

Ye and the 1 -1 1 scale just crashed the s3rv3r

grand flower
#

I'm probably gonna try to tinker with it into working but I really hope we get a permanent fix soon

restive turret
#

Also is the deforming the player still works?

#

Either was in Dr.B or CT

grand flower
#

I actually forgot to disable it

#

but it hasn't broken anything so

#

¯_(ツ)_/¯

#

Main source was pets, if you changed their role a few times they'd explode

restive turret
#

Wtf

grand flower
#

yeah someone found that out and decided it'd be funny to do it a few times in a row

#

machine just completely became unresponsive after the like, 3rd crash

restive turret
#

Wow

grand flower
#

so I just disabled them for now

restive turret
#

Add a time limit

grand flower
#

I think I can probably get them stable again but I have bigger fish to fry

#

nah, that'd be a bandaid

#

i'm guessing even if you do it with a minute apart it breaks

#

it wasn't like, multiple role changes a second

#

Scaling should've just been a sync var on a component in the reference hub, not role based

#

😭

unique crane
#

Good news is that I have branch with fix

#

for the role changed set

grand flower
#

sweet

unique crane
#

Every other value resets

#

and this one wont

#

Think about it

grand flower
#

and it would run before OnPlayerChangedRole

#

meaning it really wouldn't affect developers at all

#

But

#

If you fixed setting the scale in OnPlayerRoleChanged, at the very least it'll be less of a pain

#

We can just modify our fake role sync to send a scale update message after the role sync one

unique crane
#
  • changing this behavior now will break other plugins
#

But yes the scale msg OnRoleChanged will be fixed

#

hopefully

grand flower
#

fingers crossed

unique crane
#

I dont want to promise you anything as

#

well yea.. sometimes things are not merged instantly

grand flower
#

Even something as nasty as this?

unique crane
#

Well bug fixes usually are

#

Especially without any LabAPI change

#

purely base game PR is merged fast

grand flower
#

But then the question would be

#

How long til 14.1.2

unique crane
#

¯_(ツ)_/¯

#

I dont decide these things

#

or dont know about them until I see them on gitlab

#

or beryl tells me

grand flower
#

Well hopefully sooner than later hah

#

Not only does the server crash but it made our machines completely unresponsive

#

RAM usage spiked for some reason

unique crane
#

When I did the same thing on Host

#

is caused infinite loop of 2 scale messages being sent again and again

#

As they were different

grand flower
#

that might explain the RAM usage

upper vapor
unique crane
#

But idk what happens on the dedicated

#

Maybe the role isnt marked as client's?

#

and it sends the message back to dedicated,

#

?

#

Causing the infinite loop

grand flower
#

maybe

#

actually

#

is the fix fully serverside?

#

because if so I could just patch it in temporarily while waiting for 14.1.2

unique crane
#

I can show you what I did

grand flower
#

that would be awesome ^-^

unique crane
#

Oh also

#

Scale property is being set in constructor

#

bad idea

grand flower
#

uh oh

#

not ideal yeah

unique crane
#

Just copied the role sync to a seperate method, removed it from Update

#

Actually removed whole Update() method

#

And put it there

#

Seems to be working fine

#

Still waiting for QA

upper vapor
unique crane
#

But this sends the role message and whatever you set in the RoleChanged at the end of the frame

upper vapor
grand flower
#

alright so patch FpcScaleController's ctor to set the backing field, and send the role data immediately instead of on next frame?

unique crane
#

Yeah just like on screenshot

grand flower
#

sec

unique crane
#

Sync code remains the same

#

as it was in the Update()

grand flower
#

harmony's giving me trouble patching the ctor

#

which is weird

#
[HarmonyPatch(typeof(FpcScaleController), [typeof(FpcMotor)])]
public static class NWFpcScaleControllerFixes
{
    [HarmonyTranspiler]
    [HarmonyDebug]
    public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, MethodBase method, ILGenerator generator)
    {
        var matcher = new CodeMatcher(instructions, generator)
            .MatchEndForward(
                new(OpCodes.Ldarg_0),
                new(OpCodes.Call),
                new(OpCodes.Call)
            )
            .Set(OpCodes.Stfld, AccessTools.Field(typeof(FpcScaleController), nameof(FpcScaleController._scale)));

        return matcher.InstructionEnumeration();
    }
}
#

this should work

#

[HarmonyPatch(typeof(FpcScaleController), MethodType.Constructor, typeof(FpcMotor))] did it

#

weird

#
IL_000D: ldarg.0
IL_000E: call       static UnityEngine.Vector3 UnityEngine.Vector3::get_one()
IL_0013: stfld      UnityEngine.Vector3 PlayerRoles.FirstPersonControl.FpcScaleController::_scale
#

kk this should be good

#

onto the rest

hearty shard
#

same for enumerators

#

and uhh Getters and Setters (but those can technically be done by replacing nameof() with set_Method

#

enumerator can too technically using get targetting method thingy prob

grand flower
#

or am I missing something

unique crane
#

No its called after you call the send method

grand flower
#

alrighty, i'll check if it works once the patches are written

celest thorn
# unique crane

Oh my part of the client now its time to start decomp of sl and rewrite thanks to this piece of code trollfancy

grand flower
#
IL_008B: call       System.Void PlayerRoles.PlayerRoleManager::InitializeNewRole(PlayerRoles.RoleTypeId targetId, PlayerRoles.RoleChangeReason reason, PlayerRoles.RoleSpawnFlags spawnFlags, Mirror.NetworkReader data)
IL_0090: ldarg.0
IL_0091: call       static System.Void BrightPlugin.Patches.Fixes.Scale.NWRoleManagerSetRolePatch::SendNewRoleInfo(PlayerRoles.PlayerRoleManager roleManager)
#

time to test

#

well

#

gotta remove all the hacky scaling stuff i did

#

Wait a second

#

@unique crane just to be certain, with your changes, that means I don't have to wait at all to send fake role sync right

#

I can do it in PlayerChangedRole and it'll be received after the real role sync message?

unique crane
#

also found out that setting the scale within one frame still crashes the server

#

bruh

celest thorn
# unique crane ??

im just joking what i meant by that piece of code we can now fully recreate the client

unique crane
#

Gotta fix that

grand flower
#

wut

#

so like

#

have i been implementing it for no reason

unique crane
#

What no

#

it works

unique crane
#

Just do prefix with return false for checking if it works in the first place

grand flower
#

takes 3 minutes and I don't have to worry about porting them to transpilers later

unique crane
#

Faster to write

#

ookay

grand flower
#

but fair

#

I did do it for Update

#

i'm gonna make the delay for fake role sync one frame out of precaution

#

if that works i'll try none

#

@unique crane can confirm scale works now, kudos

#

testing fake role sync on same frame

#

it works

#

thank you so much

#

i'm gonna be able to get rid of so many delays

restive turret
unique crane
#

player.Scale = new Vector3(0.5, 0.5, 0.5);
player.Scale = new Vector3(0.51, 0.51, 0.51);

#

this will still crash the server

restive turret
#

Lmao

#

Why

unique crane
#

idk

#

I made debug build right now to find out

grand flower
#

that's spooky

restive turret
#

Spooky Scary Scale

upper vapor
#

spooky scare scale message
that shivers down my spine
-# idk the lyrics

grand flower
#

can't see how that would like

#

break

#

just from the decompiled code

#

so good luck

unique crane
#

Another day thanking God for "Attach unity debugger"

restive turret
#

I guess tried to foreach the loop while insufe it?

restive turret
grand flower
#

wouldn't crash like this

#

the only thing I could see maybe is this being ran on the host player

#

and if you set it twice in the same frame, the first message and the second message play infinite ping pong

restive turret
#

Ye

upper vapor
#

yeah uh

#

this also sends to dedicated server

restive turret
#

Lmao

upper vapor
#

who decided to do that in the constructor

grand flower
#

david pressed the "attach plugin devs to problem" button

restive turret
#

*attract

grand flower
#

079 is fighting back

#

it doesn't wanna be fixed

restive turret
#

Lmao

upper vapor
#

😭

#

what if crimson secretly hates you

restive turret
#

Many stuff doesn't wanna be fixed i guess

upper vapor
#

"you and your bright's bullshit"

grand flower
#

😭

#

it's a vanilla server too

#

like this ain't modded at all

#

and can happen in regular gameplay

restive turret
grand flower
#

they're like

#

7 minutes apart

grand flower
#

20 minutes

#

2:46 am pdt

unique crane
#

I guess it does

grand flower
#

it's the only thing I could see happening

worn gull
#

Hi! How can I check from the DamageHandler if the player died in PocketDimension?

hearty shard
#

is UniversalDamageHandler

#

.TranslationId == (translation id of pocket dimension)

worn gull
#

Thanks

restive turret
#

D

grand flower
#

eez

unique crane
#

@grand flower Yep

random scaffold
#

no

grand flower
#

I was right?

unique crane
#

Infinite loop

grand flower
#

at least it wasn't some esoteric bug

unique crane
#

But why tf does server receive it again??

random scaffold
#

Interesting fact: you don't have to run the coroutine every round

grand flower
#

dedi player is also the server right

#

so NetworkServer.active would return true

#

so when it does .Scale = when receiving the messages

#

it sends another

unique crane
#

Yeah

#

well

#

SendToHubsConditionally it is

grand flower
#

i'll apply that to my patches

restive turret
unique crane
#

Yeah

restive turret
#

David

#

When more events for 3114 and 079

upper vapor
#

me when the server is authenticated

grand flower
#

what's the check again

#

to see if a hub is the host

upper vapor
#

isLocalPlayer

#

or instancemode dedicated

unique crane
#

I did I just did hub.authManager.InstanceMode is ReadyClient

upper vapor
#

what if it breaks something niche that the server is supposed to receive toomuchtrolling

unique crane
#

Hmmm no

upper vapor
#

the whole game has to be tested now

unique crane
grand flower
#

im guessing he's only doing it for Scale

unique crane
#

I changed just the scale code

upper vapor
#

oh

#

phew

#

okay

unique crane
#

from SendToAuth

#

to SendToCondtionally

grand flower
#

gonna test that locally

unique crane
grand flower
#

we don't touch it atm so it's fine

unique crane
grand flower
#
[HarmonyPatch(typeof(FpcScaleController), nameof(FpcScaleController.Scale), MethodType.Setter)]
public static class NWFpcScaleSetterFixes
{
    [HarmonyPrefix]
    public static bool Prefix(FpcScaleController __instance, Vector3 value)
    {
        if (value == __instance._scale)
        {
            return false;
        }
        
        __instance._scale = value;
        __instance.Hub.transform.localScale = new Vector3(__instance._scale.x, __instance._scale.y, __instance._scale.z);
        if (!NetworkServer.active || __instance.Motor.Hub == null)
        {
            return false;
        }
        
        new SyncedScaleMessages.ScaleMessage(__instance._scale, __instance.Hub)
            .SendToHubsConditionally(hub => hub.authManager && hub.authManager.InstanceMode == ClientInstanceMode.ReadyClient);
        return false;
    }
}
unique crane
#

wait what I was smoking with the localScale set

grand flower
#

uh

#

oh yeah you can just assign

#

LOL

#

yep that works

#

can assign the scale a billion times now

#

awesome

hearty shard
unique crane
#

Mini micro nano optimalization of not creating a new delegate object every call

hearty shard
#

i didnt even know that was possible

upper vapor
#

(extra line)

unique crane
#

I do that too

#

You never know

upper vapor
#

shock

hearty shard
unique crane
#

It may revolt

grand flower
#

I'm an Unreal Engine developer

#

lines don't scare me

#

the coding standards forbid abbreviations

unique crane
hearty shard
grand flower
#

I very much like Blueprints if you don't use them for gameplay code

unique crane
#

ofc

#

Good for modding (I dont know c++ that good)

grand flower
#

The worst thing about working for clients is when they do their gameplay in C++, then Blueprints, which calls C++, which calls 3 different Blueprints

#

something breaks, I have to hop back and forth between the two and is it exhausting

#

They're still good for gameplay, but like

#

UI, stuff that designers wanna do, prototyping

unique crane
#

Yeah prototyping

grand flower
#

anything that's really the core gameplay you wanna do in C++ otherwise it makes maintenance hell

unique crane
#

Lets not open my PD3 mod

#

project

#

spaghetti code got a new meaning

grand flower
#

Alright it's 5 am

#

I opened the PR for Brights, I sleep

#

actually fuck forgot something for work bwahaha

#

fml

unique crane
#

Imagine not having afternoon right now

grand flower
#

guess i'm sleeping at 6 am

grand flower
unique crane
#

rip

harsh thorn
#

imagine only just now waking up at 1:50pm

#

😎

royal mica
#

waking up at 8am for meeting pepeW

harsh thorn
#

truly the life

royal mica
#

i love the endless perpetual morning standup meetings

restive turret
celest thorn
harsh thorn
#

i dont

celest thorn
#

Idk

#

i just wake up at 4 am

#

my normal routine

#

go to sleep at 1 am wake up at 4

harsh thorn
#

that is not enough 😭

celest thorn
#

yea that is

#

i pretty much did it for 5 years

#

and hey im still here

unique crane
celest thorn
#

when you develop for american servers

#

thats what you gonna do

unique crane
#

How are you still alive

celest thorn
#

and + this is useful for exams

unique crane
#

Ah yes 3 hour sleep is useful for exams right

#

I would die if I went to my maturita with 3 hours of sleep

celest thorn
celest thorn
#

i thought it was called like that only in italy

unique crane
#

matura

#

maturita

celest thorn
#

yea? that comes from latin / italian

unique crane
#

Its called maturita in czech republic

celest thorn
upper vapor
#

érettségi

celest thorn
#

but probably exams

upper vapor
#

matura

#

yea

celest thorn
#

ah

upper vapor
#

it's uh

celest thorn
#

ok

upper vapor
#

"érett" = mature
plus a bunch of suffixes

celest thorn
#

crazy

upper vapor
#

matureness-an

#

that sounds so wrong

celest thorn
#

thats how it sounds in italian

upper vapor
restive turret
#

After finished my maturita can't really woke up at 8 am

royal mica
icy wraith
#

Is it me, or changing the scale with the new scalefpccontroller when the role is chznged crashes the server?

restive turret
#

Yes known

#

David and Cyn fixed it

#

Scroll up you see cyns patch

#

Or wait till 14.1.2 (or 14.1.1.1 ClassDTroll1 )

icy wraith
#

Thanks!

restive turret
ionic prawn
#

how should i add text to the screen like who is spectating you, what effects you have

hearty shard
#

create a hint framework

#

or use ruei

royal mica
teal junco
#

some plugins show the hint their player is experiencing to the spectator which is cook

#

it may be proprietary

upper vapor
#

it takes one extension method shrug

plain gazelle
#

With the new scale module in the fpc thingy, what would be the intended way of getting the fpc thing and then setting a players height?
Im not that well-versed with the things

restive turret
#

If not works just.
Var lsc = Player.scale;
lsc.y += 0.5;
Player.scale = lsc;

upper vapor
#

add a bit of delay if you do it on role change

plain gazelle
restive turret
#

Yeah happened on our end too

plain gazelle
#

With Exiled or LabAPI?

restive turret
#

Might need to tp up after applying high

plain gazelle
restive turret
#

I certainly think it was the new .Scale

plain gazelle
#

hmm ill see, thank you

true cedar
#

i need to figure out how to support animated hint parameters

icy knoll
#

wait why wasnt the animation stuff a hint effect 😭

icy knoll
#

there is hint params and hint effects

#

why wasnt the animation a hint effect? or does it only affect {0} {1} stuff or?

hearty shard
#

#nullable disable
namespace Hints
{
  public class AnimationCurveHintParameter : HintParameter
  {
    [OriginalAttributes(FieldAttributes.Private)]
    public double _offset;
    [OriginalAttributes(FieldAttributes.Private)]
    public string _format;
    [OriginalAttributes(FieldAttributes.Private)]
    public bool _integral;
    [OriginalAttributes(FieldAttributes.Private)]
    public AnimationCurve _curve;

    public static AnimationCurveHintParameter FromNetwork(NetworkReader reader)
    {
      AnimationCurveHintParameter curveHintParameter = new AnimationCurveHintParameter();
      curveHintParameter.Deserialize(reader);
      return curveHintParameter;
    }

    public AnimationCurveHintParameter(
      double offset,
      AnimationCurve curve,
      string format,
      bool integral)
    {
      this._offset = offset;
      this._curve = curve;
      this._format = format;
      this._integral = integral;
    }

    public override void Serialize(NetworkWriter writer)
    {
      writer.WriteDouble(this._offset);
      writer.WriteString(this._format);
      writer.WriteBool(this._integral);
      writer.WriteAnimationCurve(this._curve);
    }

    public override void Deserialize(NetworkReader reader)
    {
      this._offset = reader.ReadDouble();
      this._format = reader.ReadString();
      this._integral = reader.ReadBool();
      this._curve = reader.ReadAnimationCurve();
    }

    [OriginalAttributes(MethodAttributes.Family)]
    public override string UpdateState(float progress)
    {
      float f = this._curve.Evaluate((float) (NetworkTime.time - this._offset));
      return this._integral ? Mathf.RoundToInt(f).ToString(this._format, (IFormatProvider) CultureInfo.InvariantCulture) : f.ToString(this._format, (IFormatProvider) CultureInfo.InvariantCulture);
    }
  }
}

worthy rune
#

effects also apply to the entire hint which isnt very usefull if you use a hint combiner

icy knoll
#

so how do animation curve hint providers work?

#

only replace stuff in string.Format() or?

worthy rune
#

same as any other param

teal junco
restive turret
icy knoll
icy knoll
hearty shard
icy knoll
#

can you show how it works or smth 😭

hearty shard
#

most things you do new()

hearty shard
#

i did

#
public override string UpdateState(float progress)
    {
      float f = this._curve.Evaluate((float) (NetworkTime.time - this._offset));
      return this._integral ? Mathf.RoundToInt(f).ToString(this._format, (IFormatProvider) CultureInfo.InvariantCulture) : f.ToString(this._format, (IFormatProvider) CultureInfo.InvariantCulture);
    }
icy knoll
#

no like

hearty shard
#

it updates state

icy knoll
#

how to set it up

icy knoll
#

i didnt know you update the state 😭

hearty shard
#

client does update it

#

yeah

#

but if you send a new one

#

to a player

#

i highly doubt itll save the old one

#

cuz what if you want to change it

#

what if you are sending a completely different one

worthy rune
#

you should use NetworkTime.time somewhere in the offset if you dont want discontinuities

hearty shard
#

ah

#

alright

worthy rune
#

you can see in the UpdateState that it uses NetworkTime.time as the way to keep everything in sync

teal junco
#

imagine the Unity HTML embeds

grand flower
#

Uh @unique crane question

#

The changes you gave me apparently break the black screen

icy knoll
unique crane
#

huh

grand flower
#

If you get killed

#

Your screen turns to black

#

After a while

teal junco
grand flower
#

And apparently what you gave me breaks that feature

#

I wonder if I can just like, only make it happen if your new role is spectator

unique crane
#

Oookay

teal junco
#

networked UI elements would be fire though

icy knoll
teal junco
#

so i can spawn a text element using a specific font in a specific spot on a players screen

unique crane
#

gonna eat my dinner and then look at it

hearty shard
teal junco
grand flower
#

Nvm its worse

#

Just getting shot does it

hearty shard
teal junco
#

I would have sold out already and added 5000 Hint ads

unique crane
#

what?

grand flower
unique crane
#

wtf XDDDDDDD

#

Bro blackout from being shot

restive turret
#

🔥

hearty shard
#

david why r u breaking everything

restive turret
#

david as a LabAPI broker ClassDTroll1

unique crane
#

Let me see if it happens in the branch build

grand flower
#

@unique crane it only happens after dying and respawning once

random scaffold
grand flower
#

it was too good to be true

random scaffold
#

but how you blackout

#

im wanna too

grand flower
#

😭

random scaffold
#

@unique crane say me how i can blackout the player

#

if you find it

unique crane
#

The blackout doesnt go away when you die

grand flower
#

Fun

#

The camera also goes wonky

#

So yeah we're just reverting

unique crane
grand flower
#

Spectating a player

#

Looks weird

#

Ignore QA spamming explosions

hearty shard
#

david what has thy done

grand flower
#

Sabotaged Bright's /s

#

I hope there's a solution because your changes are great

unique crane
grand flower
#

Player is shown at 0 0 0

#

For the spectator

unique crane
#

@grand flower new idea: Instead of removing the 1 frame delay we move the event to the 1 frame delay

#

And keep the scale fix ofc

grand flower
#

Uh

#

Hm

#

Maybe

#

I'd check if you're still able to get the event to run for when the player disconnects

#

(Destroyed role)

#

But that could work

#

The only downside to this is that changing/changed will now run on different frames

#

Dunno if that'll break anyone's code

icy knoll
#

why does giving items in PlayerSpawnedEventArgs not work? I have a log that says that an item should be given to a player but it's not, when it's directly before it

#

do I need to do Timing.CallDelayed() on this or? 😭

foggy stirrup
#

use exiled

icy knoll
foggy stirrup
#

yes

icy knoll
#

i just migrated off of exiled because i dont like it anymore

#

all my future plugins arent going to use exiled either

worthy rune
#

there should be a receiving loadout event, use that instead

icy knoll
#

so lets not say "use exiled instead" whenever someone asks a labapi question, ok?

icy knoll
worthy rune
icy knoll
icy knoll
grand flower
#

Programmers are getting younger and younger by the day, impressive

icy knoll
#

lets hope and pray

worthy rune
#

if that makes sense

icy knoll
#

hmm

#

yeah

#

also, is it possible to change the volume of a message via PlayerReceivingVoiceMessageEventArgs?

#

like only on that specific players side

upper vapor
#

decode, amplify, encode

icy knoll
#

well

#

it gives the data

#

so dont need to decode do I?

upper vapor
#

do you have the samples?

icy knoll
#

just the byte[]

upper vapor
#

you gotta decode that

icy knoll
#

is there in-game methods for that?

upper vapor
#

use an OpusDecoder and OpusEncoder

icy knoll
#

me when OpusDecoder requires the samples to decode

upper vapor
#

no

#

it needs a buffer to decode to

icy knoll
upper vapor
#

also you're probably gonna have horrible performance by doing so

teal junco
#

he means opus decoder and encoder every frame i think

upper vapor
#

i managed to crash the server (and sometimes clients) with like 10 encoders in parallel

icy knoll
#

hmm

teal junco
#

is there a more direct way to amplify

upper vapor
#

no

#

it's opus

#

highly compressed audio

icy knoll
#

maybe i need to save the decoded message once it's being sent, and then grab it in the recieve

#

idk what would be the best method for that tho...

upper vapor
#

yeah that's better

icy knoll
#

how would you guys recommend that be done?

unique crane
#

Or put them into seperate queue for processing

#

and sent when they are ready

#

on seperate thread

#

ofc

icy knoll
#

wait

#

ig i could use Opus stuff on a seperate thread

upper vapor
#

also, can you do this with speaker toys?

icy knoll
#

wouldnt tank performance then no?

unique crane
#

ofc

#

Why not

unique crane
icy knoll
unique crane
#

But like

#

Try it and seeeee

upper vapor
#

then you should switch to speaker toys and sync vars

icy knoll
#

nevermind then id rather it be as quick as possible then 😭

icy knoll
unique crane
#

Well like I would try it and see

#

If its just one decode and encode

upper vapor
#

i'll have something for that soon™️ :3

#

they made the tm bigger?????

icy knoll
#

ig

#

but like

unique crane
#

?

icy knoll
#

what would you guys recommend for this fr 😭

#

different thread for each reciever

#

decode during sending

#

or

#

a different method

#

i just dont know how id handle decode during sending and then grabbing on recieving

#

seems quite hard 😭

grand flower
#

@unique crane Watcha think about a "PlayerRoleSent" event

icy knoll
#

considering the data is coming in like that quickly

grand flower
#

Called in that Update function after sending the data to the players

#

That way you don't break the changed event

#

Although it can be a bit more confusing for devs

unique crane
#

Yeah..

grand flower
#

Yeah nvm

#

Well hopefully the changed event being there doesn't break anything

upper vapor
#

hopefully opus supports multiple threads

#

you also gotta initialize and dispose of the decoder in that thread

icy knoll
#

simple

upper vapor
#

how about Awaitables instead

icy knoll
#

show

#

idk what those are

#

i know what await is

#

promise ofc

upper vapor
#
public static Awaitable SendAmplified(VoiceMessage message, List<Player> targets)
{
    await Awaitable.BackgroundThreadAsync();
    // decode, amplify, encode
    await Awaitable.MainThreadAsync();
    // send
}
#

personalizing this is not nice with voice messages

icy knoll
#

wdym as send? like send to client? isn't that bad on another thread?

upper vapor
#

await Awaitable.MainThreadAsync();

icy knoll
#

yeah but you did // send after that

#

what do i send 😭

#

ohhhh

#

you send it back to the main thread

#

gotcha

upper vapor
#

yeea

icy knoll
#

public static Awaitable ModifyVolume

upper vapor
#

make it async

icy knoll
#

async Awaitable

#

ah

#

gotcha

upper vapor
#

i forgor

icy knoll
upper vapor
#

do NOT reallocate the buffers 😭

#

also using OpusEncoder

#

and decoder

#

otherwise it looks good :3

icy knoll
upper vapor
#

well... you still have to send the message

#

can't send the same thing to everyone

icy knoll
#

it's a ref, no?

upper vapor
#

you can group by volume

icy knoll
#

so it wont update on everyone's client right?

#

or nah

upper vapor
#

wait so you wanna personalize it?

icy knoll
#

every client will have a different volume set

upper vapor
#

yeah

icy knoll
#

so i want everyone to kind of have a different voice message come out lol

upper vapor
#

you can't have ref params in async methods
voicemessage is a struct anway

icy knoll
#

with different volumes

#

so how would you say I do this?

#

because im stuck here now 😭

upper vapor
#

speakertoys and fake sync vars

#

side effect: local muting doesn't work

icy knoll
upper vapor
#

oh

#

you wanna control the volume of each player

#

per client

icy knoll
#

i just wanna control the volume of intercom via server specific settings

#

that's it

#

rn ive got a two button setting that lets you mute

#

works fine

#

but i wanna make it a volume instead

upper vapor
#

intercom is not spatial though

#

or you wanted to send it through 079 speakers?

icy knoll
#

well intercom does go through 079 speakers right?

upper vapor
#

no

icy knoll
#

damn

#

so like is this even possible then? 😭

upper vapor
#

just make a non-spatial speaker toy

icy knoll
#

on each player?

upper vapor
#

no

#

fake sync vars :3

#

but then you won't have the intercom reverb

#

ugh

icy knoll
#

this is starting to sound a bit more impossible now 😭

upper vapor
#

okay

upper vapor
#

group the receivers by volume setting (linq has groupby)

#

decode once for each packet

icy knoll
upper vapor
#

amplify per group

upper vapor
icy knoll
#

fair

upper vapor
#

make it a dropdown with like 5 options toomuchtrolling

icy knoll
upper vapor
#

in the sending event

icy knoll
#

imagine if it gets the wrong value or smth

#

idk

upper vapor
#

how

upper vapor
icy knoll
#

like

#

OnSending => List.Add(msg)

#

OnRecieving => List????

upper vapor
#

uh

#

no

#

cancel the event

#

send the original message to those who have it on 100%

#

group the rest

icy knoll
#

this sounds like smth for recieving not sending 😭

pine parcel
upper vapor
#

cancel the sending event

#

send the message yourself

icy knoll
#

ohhh so modify on sending

#

*does sending tell you who the msg is being sent to? 😭 *

upper vapor
#

it's the intercom message

#

you don't need to know the receivers, everyone is

icy knoll
#

what about in proximity chat msgs tho and stuff

upper vapor
#

you want proximity chat volume too?

#

kind of a death wish

icy knoll
#

scp proximity chat

upper vapor
#

have you tried

#

telling the players to stop crying

#

that would be more ideal with speakers tbf

icy knoll
#

so many have said

#

"it's too loud"

#

i disagree

#

😭

upper vapor
#

have they paid for your patreon

#

on your server

#

if not, silence peasants toomuchtrolling

#

oh i get why it's too loud

#

cuz it isn't spatial

#

honestly

#

make proximity chat with speakers

#

and see if thedy're happy

icy knoll
#

the plugin i use does use speakers

#

lol

#

sadly it is exiled

#

as idk a labapi version and im too lazy to code it 😭

upper vapor
#

me when a player leaving doesn't remove the opush handler

icy knoll
#

😭

upper vapor
#

i love memory leaks

icy knoll
#

wait

#

this means that this constantly will use more and more memory 😭

#

wait nvm

#

wait nvm again

#

mb

#

lol

icy knoll
#

well

#

hopefully someone makes scp prox chat in labapi soon

unique crane
#

Do it

icy knoll
#

and it isn't chatgpt code

icy knoll
upper vapor
#

do i speedrun it

unique crane
#

Then just say no to laziness

#

lol

icy knoll
#

and id probably require secretapi for it or smth so that i could make player specific volume ssss stuff

upper vapor
#

i can stream the speedrun in vc :3

icy knoll
#

because idk ssss stuff without secretapi or exiled

#

and exiled is pretty crap for that stuff 😭

icy knoll
upper vapor
#

i won't mem leak

icy knoll
unique crane
icy knoll
upper vapor
#

im hypixleing so

#

in sopme minutes

plain gazelle
#

Player.Inventory.ServerRemoveItem requires a ItemPickupBase, but i only have an Item. How can i use this function if i dont have a Pickup, since it is in their Inventory?

upper vapor
#

set it to null

#

if you just wanna remove it

plain gazelle
#

Ohhh, that is what it would "become"
Alright, thank you

upper vapor
#

also if you have the player i'm pretty sure you could just player.RemoveItem(item)

plain gazelle
#

I tried that but for some reason it leaves a ghost item in my inventory until i update it

upper vapor
icy knoll
plain gazelle
# upper vapor wha
  • Give revolver
  • Hold revolver
  • player.RemoveItem(revolver.Base)
  • Ingame the Revolver gets 'holstered'
  • Cant take it back out by clicking it
  • Cant drop it by clicking it
  • If i pick up a new item like a medkit, the revolver disappears out of my inventory
#

So like, it gets deleted server side, but not client side, idk

worthy rune
#

player.RemoveItem and Player.Inventory.ServerRemoveItem are the same, could we see the code you wrote?

plain gazelle
#

Oh i think i accidentally did
player.Inventory.UserInventory.Items.Remove
wups :x

upper vapor
#

oops

grand flower
#

@unique crane about to patch the PlayerRoleChanged event to be in Update() after sendNextFrame

#

Did you try it yet? If not I'll just let you know how that goes

unique crane
#

No I didnt yet

grand flower
#

Fingers crossed nothing breaks

#

sl modding moment

random scaffold
#

nw moment

grand flower
#

having a second monitor with dotpeek is sweet

#

can just copy il over

upper vapor
#

@icy knoll you up?

grand flower
#
[HarmonyPatch(typeof(PlayerRoleManager), nameof(PlayerRoleManager.Update))]
public static class NWRoleManagerDisableUpdate
{
    [HarmonyTranspiler]
    [HarmonyDebug]
    public static IEnumerable<CodeInstruction> Update_Transpiler(IEnumerable<CodeInstruction> instructions, MethodBase method, ILGenerator generator)
    {
        var matcher = new CodeMatcher(instructions, generator)
            .End()
            .MatchEndBackwards(new CodeMatch(OpCodes.Ret))
            .Advance(-1) // Go behind the ret
            .Insert(
                new(OpCodes.Ldarg_0),
                new(OpCodes.Ldfld, AccessTools.Field(typeof(PlayerRoleManager), nameof(PlayerRoleManager._hub))),
                new(OpCodes.Ldloc_1),
                new(OpCodes.Ldarg_0),
                new(OpCodes.Call, AccessTools.PropertyGetter(typeof(PlayerRoleManager), nameof(PlayerRoleManager.CurrentRole))),
                new(OpCodes.Ldarg_2),
                new(OpCodes.Ldarg_3),
                new(OpCodes.Newobj, AccessTools.Constructor(typeof(PlayerChangedRoleEventArgs),
                    [typeof(ReferenceHub), typeof(RoleTypeId), typeof(PlayerRoleBase), typeof(RoleChangeReason), typeof(RoleSpawnFlags)])),
                new(OpCodes.Call, AccessTools.Method(typeof(PlayerEvents), nameof(PlayerEvents.OnChangedRole)))
            );

        return matcher.InstructionEnumeration();
    }
}

// Removes the call to PlayerEvents.OnChangedRole() to move it to Update.
[HarmonyPatch(typeof(PlayerRoleManager), nameof(PlayerRoleManager.ServerSetRole))]
public static class NWRoleManagerSetRolePatch
{
    [HarmonyTranspiler]
    [HarmonyDebug]
    public static IEnumerable<CodeInstruction> ServerSetRole_Transpiler(IEnumerable<CodeInstruction> instructions, MethodBase method, ILGenerator generator)
    {
        var matcher = new CodeMatcher(instructions, generator)
            .MatchEndForward(
                new(OpCodes.Ldarg_0),
                new(OpCodes.Ldc_I4_1),
                new(OpCodes.Stfld, AccessTools.Field(typeof(PlayerRoleManager), nameof(PlayerRoleManager._sendNextFrame)))
            )
            .Advance(1);

        // Removes LabApi.Events.Handlers.PlayerEvents.OnChangedRole(new PlayerChangedRoleEventArgs(this._hub, roleTypeId, this.CurrentRole, reason, spawnFlags));
        return matcher
            .RemoveInstructions(matcher.Remaining)
            .InstructionEnumeration();
    }
}
#

should hopefully work

#

let's see

#

ah fuck

#

can't access the reason

#

from Update()

#

fuck it no more transpilers

restive turret
#

@rare hinge yo how did u fix the

                                   at Microsoft.CSharp.CSharpCodeGenerator.FromFileBatch (System.CodeDom.Compiler.CompilerParameters options, System.String[] fileNames) [0x00186] in <fba24a13802445559d6435422e829b75>:0
                                   at Microsoft.CSharp.CSharpCodeGenerator.System.CodeDom.Compiler.ICodeCompiler.CompileAssemblyFromFileBatch (System.CodeDom.Compiler.CompilerParameters options, System.String[] fileNames) [0x0003a] in <fba24a13802445559d6435422e829b75>:0
                                   at System.CodeDom.Compiler.CodeDomProvider.CompileAssemblyFromFile (System.CodeDom.Compiler.CompilerParameters options, System.String[] fileNames) [0x00006] in <fba24a13802445559d6435422e829b75>:0``` 
error?
random scaffold
#

how i can get path to .config\SCP Secret Laboratory\LabAPI\configs?

#

from configuration loader or something

upper vapor
#

PathManager

random scaffold
#

magic

true cedar
unique crane
icy knoll
grand flower
#

[HarmonyPatch(typeof(PlayerRoleManager))]
public static class NWPlayerRoleManagerPatches
{
    private static readonly Dictionary<uint, PlayerChangedRoleEventArgs> _pendingEvents = new();
    
    public static void OnChangedRole(PlayerChangedRoleEventArgs args)
    {
        _pendingEvents.Remove(args.Player.NetworkId);
        
        // Role is destroyed/none, fire immediately.
        if (args.NewRole.RoleTypeId is (RoleTypeId.Destroyed or RoleTypeId.None))
        {
            PlayerEvents.OnChangedRole(args);
            return;
        }
        
        // Add the event to the player's pending events, which will be used on the next frame.
        _pendingEvents[args.Player.NetworkId] = args;
    }

    public static void FirePendingEvents(ReferenceHub hub)
    {
        var player = Player.Get(hub);

        if (!player.IsValid())
        {
            return;
        }

        if (_pendingEvents.TryGetValue(player.NetworkId, out var args))
        {
            PlayerEvents.OnChangedRole(args);
            _pendingEvents.Remove(player.NetworkId);
        }
    }
    
    [HarmonyPatch(nameof(PlayerRoleManager.Update))]
    [HarmonyTranspiler]
    [HarmonyDebug]
    public static IEnumerable<CodeInstruction> Update_Transpiler(IEnumerable<CodeInstruction> instructions, MethodBase method, ILGenerator generator)
    {
        var matcher = new CodeMatcher(instructions, generator)
            .End()
            .MatchEndBackwards(new CodeMatch(OpCodes.Ret))
            .SetOpcodeAndAdvance(OpCodes.Nop)
            .InsertAndAdvance(
                new(OpCodes.Ldarg_0),
                new(OpCodes.Ldfld, AccessTools.Field(typeof(PlayerRoleManager), nameof(PlayerRoleManager._hub))),
                new(OpCodes.Call, AccessTools.Method(typeof(NWPlayerRoleManagerPatches), nameof(FirePendingEvents)))
            );

        return matcher.InstructionEnumeration();
    }
    
    [HarmonyPatch(nameof(PlayerRoleManager.ServerSetRole))]
    [HarmonyTranspiler]
    [HarmonyDebug]
    public static IEnumerable<CodeInstruction> ServerSetRole_Transpiler(IEnumerable<CodeInstruction> instructions, MethodBase method, ILGenerator generator)
    {
        var matcher = new CodeMatcher(instructions, generator)
            .MatchEndForward(
                new(OpCodes.Ldarg_0),
                new(OpCodes.Ldfld),
                new(OpCodes.Ldloc_1),
                new(OpCodes.Ldarg_0),
                new(OpCodes.Call),
                new(OpCodes.Ldarg_2),
                new(OpCodes.Ldarg_3),
                new(OpCodes.Newobj),
                new(OpCodes.Call)
            )
            .SetOperandAndAdvance(AccessTools.Method(typeof(NWPlayerRoleManagerPatches), nameof(OnChangedRole)));

        return matcher.InstructionEnumeration();
    }
}
#

trying this

#

@unique crane so it works

#

however the first time the player spawns it seems to work differently?

#

like

#

hmmm

#

Everything seems to work fine

#

the bugs are gone

#

i'll debug why the scale isn't correct on first spawn

restive turret
#

Cyn, is harmony's UnpatchAll removes every patch and not just patches that made with only that assembly?

grand flower
#

unsure

#

we don't remove em because memory leaks

worthy rune
#

oh it does?

hearty shard
#

Yes

#

i think

#

i might be schizo

worthy rune
#

how much roughly

hearty shard
#

I remember that being a bug

grand flower
restive turret
#

Idk tho
I always unregister with the id

grand flower
#

I just saw it as a comment in our codebase and decided not to ask questions

hearty shard
#

oh i think

#

its cuz harmony.UnPatchAll()

#

Without supplying an id

worthy rune
#

you can do this harmony.UnpatchAll(harmony.Id);

hearty shard
#

Yeah

worthy rune
#

if you only want to unpatch the ones you applied to that instance

hearty shard
#

The issue is that when you dont specify id despite it being part of the instance method.. it does all

#

Idk why

#

Harmony moment

worthy rune
#

yeah xD

restive turret
hearty shard
#

shouldve been static method but oh well

restive turret
#

Anyway, sad that SL doesn't ship mono.exe on server

grand flower
#

now I have a weird bug

#

ServerSetRole fires PlayerChangedRole

#

But Update never calls

#

hmmm

#

it's if you call Server Set Role inside PlayerRoleChanged

#

@unique crane Looks like this would solve it, excellent idea

#

we're gonna put it on our test server and get players to hang out on it a little to make sure it doesn't implode

#

But tldr what I did was:

  • In ServerSetRole, only call PlayerEvents.OnChangedRole immediately if the new role is Destroyed or None (unsure None is needed but w/e)
  • If it isn't, hold the changed role args.
  • In Update(), after sending the role sync data, if there's a pending event, execute it.
#

Bonus is you can set the player's position/rotation in PlayerChangedRole now and it works with no delays

#
[HarmonyPatch(typeof(PlayerRoleManager))]
public static class NWPlayerRoleManagerPatches
{
    private static readonly Dictionary<uint, PlayerChangedRoleEventArgs> _pendingEvents = new();
    
    public static void OnChangedRole(PlayerChangedRoleEventArgs args)
    {
        _pendingEvents.Remove(args.Player.NetworkId);
        
        // Role is destroyed/none, fire immediately.
        if (args.NewRole.RoleTypeId is (RoleTypeId.Destroyed or RoleTypeId.None))
        {
            PlayerEvents.OnChangedRole(args);
            return;
        }
        
        // Add the event to the player's pending events, which will be used on the next frame.
        _pendingEvents[args.Player.NetworkId] = args;
    }

    public static void FirePendingEvents(ReferenceHub hub)
    {
        var player = Player.Get(hub);

        if (!player.IsValid())
        {
            return;
        }

        if (_pendingEvents.TryGetValue(player.NetworkId, out var args))
        {
            _pendingEvents.Remove(player.NetworkId);
            PlayerEvents.OnChangedRole(args);
        }
    }
    
    [HarmonyPatch(nameof(PlayerRoleManager.Update))]
    [HarmonyTranspiler]
    public static IEnumerable<CodeInstruction> Update_Transpiler(IEnumerable<CodeInstruction> instructions, MethodBase method, ILGenerator generator)
    {
        var matcher = new CodeMatcher(instructions, generator)
            .End()
            .MatchEndBackwards(new CodeMatch(OpCodes.Ret))
            .SetOpcodeAndAdvance(OpCodes.Nop)
            .InsertAndAdvance(
                new(OpCodes.Ldarg_0),
                new(OpCodes.Ldfld, AccessTools.Field(typeof(PlayerRoleManager), nameof(PlayerRoleManager._hub))),
                new(OpCodes.Call, AccessTools.Method(typeof(NWPlayerRoleManagerPatches), nameof(FirePendingEvents)))
            );

        return matcher.InstructionEnumeration();
    }
    
    [HarmonyPatch(nameof(PlayerRoleManager.ServerSetRole))]
    [HarmonyTranspiler]
    public static IEnumerable<CodeInstruction> ServerSetRole_Transpiler(IEnumerable<CodeInstruction> instructions, MethodBase method, ILGenerator generator)
    {
        var matcher = new CodeMatcher(instructions, generator)
            .MatchEndForward(
                new(OpCodes.Ldarg_0),
                new(OpCodes.Ldfld),
                new(OpCodes.Ldloc_1),
                new(OpCodes.Ldarg_0),
                new(OpCodes.Call),
                new(OpCodes.Ldarg_2),
                new(OpCodes.Ldarg_3),
                new(OpCodes.Newobj),
                new(OpCodes.Call)
            )
            .SetOperandAndAdvance(AccessTools.Method(typeof(NWPlayerRoleManagerPatches), nameof(OnChangedRole)));

        return matcher.InstructionEnumeration();
    }
}
flat vine
#

Can someone explain where is the rule that prohibits the use of AI generated images ?

grand flower
#

I'd contact moderation directly

flat vine
#

It is not really nice to delete 2 posts with plugins without explanation (I could have just deleted the attachment from the topic)

restive turret
#

I love discord forums breaking my phone

languid temple
flat vine
restive turret
flat vine
restive turret
#

Or whatever dc calls that

flat vine
restive turret
#

Not my issue, I dont use AI for these stuff ClassDTroll1

languid temple
hearty shard
#

whys there points

#

pls explain thanks

languid temple
hearty shard
#

well

#

not what do they do but how are they used

#

the rules specify amount of warns = punishment, unless im blind i dont see anything related to how the warning points are used

languid temple
languid temple
#

Why what did you think?

hearty shard
#

Like youd give different punishments different amount of points

#

But instead its literally just a counter of the amount

languid temple
#

ye

slender lynx
#

@flat vine make them in ms paint

grand flower
flat vine
slender lynx
#

knowyourcoroutines is crazy useful

flat vine
#

give me some time to do some Photoshop

random scaffold
#

how i can disable limit to view?

flat vine
random scaffold
worthy rune
#

1

flat vine
#

☝️

random scaffold
#

MAGIC

#

how much render distance?

#

for primitives

flat vine
random scaffold
#

how much need intensity?

#

intensity 50 now

#

and range 120

grand flower
#

Whenever teleporting a player to another player that's in an elevator, is there a way to force the teleported player's waypoint to be the elevator's?

#

that way it doesn't fall through it?

random scaffold
#
  • 0, 0.25
grand flower
#

also, is there a way to increase the jump height of SCP-096

carmine prawn
#

Player.Gravity

unique crane
#

When you teleport to someone while in the elevator

upper vapor
#

@icy knoll btw, the SSSS keybind doesn't work whatsoever, no log

#

-# with secretapi

grand flower
#

all good

grand flower
carmine prawn
#

I tried patch some, but

#

not sync

icy knoll
slate flume
#

Is there a way I can uh make primitives not shiny

#

It has this weird stippling effect from reflections that are gross and icky

upper vapor
slate flume
#

Oh

#

Interesting

#

You probably right

upper vapor
#

also you can't set the material's metallic or smoothness props

slate flume
#

That's lame

#

Okay yeah you werer right

#

That's much better

upper vapor
#

@hearty shard how did you get around this

#

you never set DefinedSettings

restive turret
#

Create a new empty array

upper vapor
#

right

#

oh

#

i'm dumb

restive turret
#

Hi dumb

grand flower
#

Need to find a way to detect a player being stuck in geometry while their scale is being increased

upper vapor
#

boxcast

#

@icy knoll

#

i installed secretapi as a dependency

#

😭😭😭😭

#

it works now

grand flower
upper vapor
#

there are multiple sphere colliders

#

but a box would probably suffice

#

if you wanna make sure, use the player model's hitboxidentities

#

what do you need

#

i don't think that's supported atm

#

you can work around it by creating a symlink

grand flower
#

hmmm

#

guessing I have to use BoxcastAll?

#

Or is there a layer I can use that only hits the map

upper vapor
#

i think simply boxcasting will work as it hits anything

upper vapor
grand flower
#

yeah

#

but Boxcast will return the first hit

#

which'll probably be the player

upper vapor
#

layermask

grand flower
#

are there constants I can use somewhere

upper vapor
#

HitscanHitregModuleBase.HitregMask maybe

#

wait no