#LC_API
1 messages · Page 2 of 1
yeah, does the NetworkMessage actually give any helpful info?
well it describes what the ulong is lol
True. that's definitely better

readthedocs
Ok it does still work as ulong, T
future me's problem when people ask questions
You could put the doc comment on the abstract method if you implement it as class annotation rather than method annotation
people can still whack a class definition anywhere
[NetworkMessage("MyActionName")]
public class MyAction : BaseAction<Vector3>
{
public override Handle(ulong senderId, Vector3 payload) {
{
...
}
}
yeah, but it's a slightly odd
sure, it might be slightly odd, but it future-proofs you
if you ever want people to be able to customise their handlers more than just the callback
you can add extra stuff to the class
if you're just decorating a method, that's making a huge assumption that users will never want more control than the callback
Well there's nothing else to control really
that's what we think for now
I wanted them to be able to access private properties in a class
😂
you ... still can
can't you?
ah yeah, private instance props
I see what you're getting at
but shouldn't a network message handler always have static context
oh yeah then no issue
classes can access private static members from enclosing classes
I personally just didn't want to make a class for every network message Iw anted
I think it's just a lot of unnecessary classes tbh
but they're not gonna be in the root namespace so why does it matter
i could say the way you're proposing is a lot of unnecessary functions
Best of both worlds
just do both
Well classes would require a function to handle
I also see no future case for having it in a class
as you do everything in the handler itself
yeah, but they ensure you get a compiler error if you set the wrong signature on your handler method
what about metadata like who is allowed to send the message
I'm not entirely convinced, but that's just how I am
Go for the method attribute syntax
I've actually tried both and it seems incredibly difficult because of the generic
Since I need to register it with the generic and an Action<ulong, T>
idek how to actually get a generic attribute off of a type
since you can't GetAttribute(Attribute<T>)
Action action = method.CreateDelegate(typeof(Action).MakeGenericType(typeof(ulong), method.GetGenericArguments()[0])) as Action; no idea if this will work, but even if it does, this is cursed.
interface IAction<out T> where T : class
{
public void Register(string uniqueName);
}
abstract class BaseAction<T> : IAction<T> where T : class
{
public abstract void Handle(ulong senderId, T payload);
public void Register(string uniqueName)
{
Networking.RegisterMessage<T>(uniqueName, Handle);
}
}
Does that do the trick?
Then wherever you're collecting the attribute you can
IAction<object> whatever = ...;
whatever.Register();
even tho the calling scope only knows it's containing an object type, the instance will know its actual T so will call the right thing
@jagged trout Thoughts?
[NetworkMessage(typeof(TestClass), "TEST_THING")]
internal static void Test(ulong senderId, TestClass thing)
{
Log.LogInfo("GOT TEST MESSAGE");
Log.LogInfo(thing.value);
}
[NetworkMessage(typeof(TestClass), "TEST_THING2")]
internal class BigTest : NetworkMessageHandler<TestClass>
{
public override void Handler(ulong sender, TestClass message)
{
Log.LogInfo("GOT TEST MESSAGE");
Log.LogInfo(message.value);
}
}
I got both of these working
I had to define the message type in the attribute
I will probably make it the 2nd argument if I don't find a way around it
getting those generics was very odd
Apparently c# attributes don't support generics as expected I don't think
I did try a register method on the attribute class, but I couldn't get it working
I'll see if I can pull the type from the params though
but tomorrow
it's 2:30 am and I'm tired
gn
yeah, the interface with covariant type param is important for that to work
sleep well!
Seems like somehow your broadcast happened before HudManager.Instance was set @grave saffron
as that's the only thing that could be null
I've never seen that happen before though
Continuing this, I got it to work with just this, too:
[NetworkMessage("TEST_THING")]
internal static void Test(ulong senderId, TestClass thing)
{
Log.LogInfo("GOT TEST MESSAGE");
Log.LogInfo(thing.value);
}
[NetworkMessage("TEST_THING2")]
internal class BigTest : NetworkMessageHandler<TestClass>
{
public override void Handler(ulong sender, TestClass message)
{
Log.LogInfo("GOT TEST MESSAGE 2");
Log.LogInfo(message.value);
}
}
by extracting the types from the method and from the generic base class
well now that it works, I'll focus on making it backward compatible...
actually
after thinking about it more, this is basically impossible to make backwards compatible
with the new system messages have to actually be registered on the network handler
ngo will just ignore ones that aren't, and since the old ones just use Broadcast and add to a delegate invoke list, there's no real efficient way to dynamically register them
I can invoke the old delegates for properly registered messages, but I can't really register any of the ones that aren't registered
Awesome, this looks brilliant
Yeah. A shame but worth it for the ease of use it'll bring in the future
latest commit to #43 adds support for network messages with no body, so they are just invoked with the sender
this is basically just to mimic RPC's with no params
And I wanted a way to send a message to clients to tell them to send their mod list, but that message doesn't require any body since we know what handler we're in
noice
ahh I getchu
what'd you need the client modlists for?
- why not have clients send them when they join, then cache the results?
I'm just working with the flow of the old system that had player mods show on join.
okay, that's fair, but do you see what I mean?
like, that might be something worth re-jigging in the future
Apparently people are having issues on 3.1.0 that I just can't seem to reproduce
I think most of the issues are caused by outdated mods and people not knowing what the point of a major version is
Though someone said LC API is causing godmode? Which I quickly tested and was not able to reproduce
I also find it somewhat funny when people report bugs for manually downloading when 99% of the time that means they pirated the game lol
@main minnow are you able to help me test like a 2 minute bug that someone is apparently having?
only asking since I saw you online
apparently someone can't pull the lever, and I tested with one person and then they said it only works with someone else in the lobby
¯_(ツ)_/¯
If you are able, 018ca6d1-941f-4d75-40fd-9f3323f0b479 this just has bepinex and lc api
could it just be that they started a new lobby
when the only one that can pull the lever is the host
they said it was mid game
are they using late company
me and my friends have been having this problem where when we leave a planet, the game gets stuck and doesn't let us go to another planet (the lever that you pull to land just gets stuck on "Waiting for ship to land." and the game also doesn't auto save because of this) and i believe it to be an issue with the game thinking that it's still on a planet even after leaving (for god knows why).
i made sure that this is an issue with LC API because after disabling LC API, the issue didn't happen anymore (no other mods i have use LC API so it was safe to disable it)
This was the whole post
they said disabling lc api made it work
idk why they have it if they don't need it
but I'd like to test it with more players regardless
just to make sure I didn't miss anything
yeah sure - lemme finish this dr who episode if that's ok? 30mins tops
aye okay
The profile code should still work 018ca6d1-941f-4d75-40fd-9f3323f0b479
aye i've used it
I'll also need your steam friend code
sure
actually your account is linked
I sent you a fr
aye got it
alright, we're literally just gonna go to 2 moons lol
cheeky game crashed
Did you need a new invite?
@main minnow does the dll not go to Release\net46 anymore on your PR?
Hm
also
Building with minver sets the version as 1.0.0 for the bepinex plugin, even though it builds the dll as 3.2.1
that'll have to be fixed before I can merge this
I'm not sure minver and the bepinex plugin info are compatible
and also netcode weave doesn't seem to work
even though it says it did
On your PR vs on main
I think the issue may be in part that it isn't going to Release/net46
and is instead just in bin
since there's no _original file, either
for some reason it also freezes the version in decomp to 3.0.0.0
Here's mine, vs yours, not sure what's going on there
That's right, sorry
I can overwrite that but minver does that intentionally by convention
I don't know why the convention is that way
Hmm okay, I'll get that fixed
I'm not entirely sure it matters, just found it odd
as long as the bepinex version is right
which atm it doesn't seem to be
Aye, I think that'll be because MinVer is setting the Version attr too late for Bepin
I'll just need to enforce the right order of the build tasks
It's hacky but I think making an empty target with Aftertargets=minver and BeforeTargets=BepIn will do the trick 😂
I have not yet released 3.2.0 as I'm waiting for your PR, but this will apply then
Gonna work on the other pages in the meantime
awesome!
I'm most likely gonna switch to a github pages and have the xml docs auto generate most of it
@jagged trout I found out why MinVer does what it does:
Assembly version
The assembly version is what the CLR uses at run time to select which version of an assembly to load. Selecting an assembly using versioning only applies to assemblies with a strong name.
<AssemblyVersion>1.0.0.0</AssemblyVersion>The .NET Framework CLR demands an exact match to load a strong-named assembly. For example,
Library1, Version=1.0.0.0was compiled with a reference toNewtonsoft.Json, Version=11.0.0.0. .NET Framework will only load that exact version11.0.0.0. To load a different version at run time, a binding redirect must be added to the .NET application's config file.
so assuming we adhere to semver, the assembly version being set that way makes sense
@jagged trout I've updated the PR, take a look when you can
Checking
Ok
I must be using the wrong file
where is the actual completed dll going?
because the one in bin/ is not netcode patched
the only _original file I have in in bin/Release/net46, but it's old
have you pulled changes?
Because for me, the DLL is going to bin/ and there is also an original in that folder
Well that would help, lol
😂😂😂😂
seems to work
I should double check it works within actions
Well I've already merged, so lemme know if it doesn't
I won't be making any github releases until 2018 can get the nuget setup as well
Where can I get a thunderstore api key?
as far as I can tell they just use basic auth
You're on the '2018' team ?
yeah
im not sure you'll have high enough privileges to add service accounts
I'm not
when you create a service account, it gives you an API key scoped to the team the account is for
okay so it'll be another thing 2018 has to do 😅
@jagged trout I borked the build badge 😭
give me a sec
PR opened
ah yes you can experience the glory of PR checks!
it brings a tear to my eye
🥹
@main minnow I haven't actually tested that the networking works on other clients, so do you think you could join me with a custom build?
Sure, let me get the restructure PR going
can I pull your branch and build it myself?
no, I have specific test changes that won't be pushed
👍
@jagged trout i've just noticed youre using net46 which doesnt support netstandard2.0
I didn't use net46
in the restructure is it ok if I target netstandard2.0
2018, OK. Targeting netstandard.
As long as it doesn't break anything
👍
ideally we should get the mod list popup then I'll get some console logs after 10 seconds
wait
I never called the test method lol
oh well, the mod list should work
also for some reason my vs didn't like that minver so it did this
¯_(ツ)_/¯
config mismatch
hm
what the fuck? 😂
try to revert this commit if you can
I didn't commit it
it also doesn't let me build if I change it
you what
but it's the same version
unload project -> edit -> reload?
and it seems to work on my end still
I don't think this should really make a difference anyways
as far as I can tell it's still working
hm
yeah but it's using the expanded view for no reason
i'll set the IncludeAssets attr on the restructure branch
I'll delete my config file so i get a clean one
hmmmmmmmmmmmmmmmmmmm
kek
it's not an actual config file
it's the like network prefabs and stuff
🤞
hmmmmmmmm
not good
wassup
I'm assuming unity ngo requires all net messages registered with RegisterNamedMessageHandler to be synced, but with mod mismatches that will almost never be the case, and for mods without lc api, would never work. I'm not sure why we can't connect, however, since we have the same mods
I'm gonna remove all the network messages just to see if we can connect
This could be a major problem
I may have to switch to unnamed messages and just make my own message handler
But first lets see if removing the messages allows you to connect
The docs don't really mention that they need to be synced anyways
in fact it just says that they should be registered in OnNetworkSpawn
so it would be impossible for them to be synced on join
You do have the networking asset bundle though, right?
Your file structure should look like this and inside that Bundles folder should be networking
I did not
I'm sorry about that, let me sort it
did you add the Bundles dir with assetbundles to Git?
you want me to download from TS?
Let me just remove Thunderstore from the gitignore
so it'll upload with it
okay
[Info :Lethal Company API] Broadcasting
[Error : Unity Log] NotServerException: ConnectedClientIds should only be accessed on server.
Stack trace:
Unity.Netcode.NetworkManager.get_ConnectedClientsIds () (at <1b23ec5fcbfc4fbca0db70afcdb9b715>:0)
Unity.Netcode.CustomMessagingManager.SendNamedMessageToAll (System.String messageName, Unity.Netcode.FastBufferWriter messageStream, Unity.Netcode.NetworkDelivery networkDelivery) (at <1b23ec5fcbfc4fbca0db70afcdb9b715>:0)
LC_API.Networking.NetworkMessageFinalizer.Send () (at <55ac7c31d7b34564b0b94f24f0a6a794>:0)
LC_API.Networking.Network.Broadcast (System.String uniqueName) (at <55ac7c31d7b34564b0b94f24f0a6a794>:0)
LC_API.Plugin+<TestSendMessage>d__14.MoveNext () (at <55ac7c31d7b34564b0b94f24f0a6a794>:0)
UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at <e27997765c1848b09d8073e5d642717a>:0)
hm
sender id is pretty much useless if I make this an rpc
not sure what to do
guess I'll also have to make it a relay...
Which means I'll need to wrap the type into a new class that has the actual sender and unpack it when received
have fun!! 😂
AUGHHHHHH
EVAIIIISAAAAA
why couldnt she just make netcodeweaver a clever thing
i'm actually going to have to write a javascript action
to make the netcode weaver setup action
i swear to fucking god
see you in a few hours
@main minnow think you could test with me again?
I think I got this wrapped relay done
it works sending to self as host, but gotta test clients as well
I actually didn't need to add anything to the bundle either
thank god
sure
@jagged trout sorry about that, whenever
Guess not lol
lol that file should still be good
alright so we're hoping for it to say broadcasting in your console then in mine I'll see a bunch of network messages
aye aye
anything?
[Info :Lethal Company API] Broadcasting
[Error : Unity Log] NullReferenceException: Object reference not set to an instance of an object
Stack trace:
LC_API.Networking.NetworkMessageFinalizer.Send () (at <1be4b194ad4840899e4c16396a912452>:0)
LC_API.Networking.Network.Broadcast (System.String uniqueName) (at <1be4b194ad4840899e4c16396a912452>:0)
LC_API.Plugin+<TestSendMessage>d__14.MoveNext () (at <1be4b194ad4840899e4c16396a912452>:0)
UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at <e27997765c1848b09d8073e5d642717a>:0)
[Error : Unity Log] NullReferenceException: Object reference not set to an instance of an object
Stack trace:
LC_API.Networking.NetworkMessageFinalizer.Read (System.UInt64 fakeSender, Unity.Netcode.FastBufferReader reader) (at <1be4b194ad4840899e4c16396a912452>:0)
Unity.Netcode.CustomMessagingManager.InvokeNamedMessage (System.UInt64 hash, System.UInt64 sender, Unity.Netcode.FastBufferReader reader, System.Int32 serializedHeaderSize) (at <1b23ec5fcbfc4fbca0db70afcdb9b715>:0)
Unity.Netcode.NamedMessage.Handle (Unity.Netcode.NetworkContext& context) (at <1b23ec5fcbfc4fbca0db70afcdb9b715>:0)
Unity.Netcode.NetworkMessageManager.ReceiveMessage[T] (Unity.Netcode.FastBufferReader reader, Unity.Netcode.NetworkContext& context, Unity.Netcode.NetworkMessageManager manager) (at <1b23ec5fcbfc4fbca0db70afcdb9b715>:0)
Unity.Netcode.NetworkMessageManager.HandleMessage (Unity.Netcode.NetworkMessageHeader& header, Unity.Netcode.FastBufferReader reader, System.UInt64 senderId, System.Single timestamp, System.Int32 serializedHeaderSize) (at <1b23ec5fcbfc4fbca0db70afcdb9b715>:0)
UnityEngine.Debug:LogException(Exception)
Unity.Netcode.NetworkMessageManager:HandleMessage(NetworkMessageHeader&, FastBufferReader, UInt64, Single, Int32)
Unity.Netcode.NetworkMessageManager:ProcessIncomingMessageQueue()
Unity.Netcode.NetworkManager:NetworkUpdate(NetworkUpdateStage)
Unity.Netcode.NetworkUpdateLoop:RunNetworkUpdateStage(NetworkUpdateStage)
Unity.Netcode.<>c:<CreateLoopSystem>b__0_0()
my pain is immeasurable
I wonder if Player.HostPlayer is null for you for some reason
Yeah it seems like for you HostPlayer and LocalPlayer are null
nah wasn't you
syncing the custom players is finnickey
especially with timing and ping
it's a nightmare
Ok, so let's try this lmao
👍
@main minnow before you continue your restructure, I'd pull main
after your restructure, I'm going to freeze main for releases and we'll work from a dev branch
Will do. Thankyou for letting me know
speaking of this feature can I have a config to turn it off :)
It's networking, if you don't make any handlers it won't do anything
wait is this not the same LC_API that spams hud elements for 5 minutes at the start of every game with cutoff lists of mods?
I completely rewrote networking
it uses ngo custom messages now
so it won't use chat anymore
so you can send whatever you want as long as it's serializable and all you gotta do is add that attribute, LC API will handle the rest
Is it automatic? I assumed it was something you had to implement yourself
well you add the attribute, that's the implementation
Yeah the other messages just loaded for me. Wi-Fi cut out
then you just do
Network.Broadcast("Name", T obj)
Nice that it doesn't just chat
Yeah that was an interesting implementation
Ouf the string tho 😔
It's gotta be named somehow
But it just uses named messages under the hood
Oh so it doesn't send the string?
the name being what you see in the attribute
No
you can send anything you want that's serializable
Cool then
this includes your own classes as long as you mark them as serializable
the wiki shows an example
What are you using to serialize the objects?
internal static byte[] ToBytes(this object @object)
{
if (@object == null) return null;
BinaryFormatter binaryFormatter = new BinaryFormatter();
MemoryStream memoryStream = new MemoryStream();
binaryFormatter.Serialize(memoryStream, @object);
return memoryStream.ToArray();
}
internal static T ToObject<T>(this byte[] bytes) where T : class
{
BinaryFormatter binaryFormatter = new BinaryFormatter();
MemoryStream memoryStream = new MemoryStream();
memoryStream.Write(bytes, 0, bytes.Length);
memoryStream.Seek(0, SeekOrigin.Begin);
return binaryFormatter.Deserialize(memoryStream) as T;
}
it's just a byte array
Doesn't binaryformatter have security issues? See: the Raft incident
raft incident?
Yeah, the game
Damn that's a shit link
If you Google raft binary formatter you'll find it
Yes, but any dev could use the remote code exploit on anyone else using LC api
Having the mod installed would be a liability
Trying to think of a solution
Don't use binary formatter
It is the only solution...
a solution to this problem is replacing it with something else
"remove it" is not helpful
Yes, removing it will be a part of the solution, but it isn't the solution entirely
I can see if json serialization will work I guess
That would bloat message sizes more than BF
Yeah, but alternative is RCE
and I'm not about to write a custom binary serializer because I would introduce more security problems than binary formatter
That's what I did
Gaffer on games has a good implementation of a custom binary serializer
The issue is it's too low level for your target audience
Well I'm not presenting any serialization to the user, I would like them to just be able to send whatever type they want and the api will serialize it for them
For more advanced users maybe
but it's not useful for most users to have to write their own serialization
Yep
@jagged trout since LCAPI is lethal company specific, you could just use Newtonsoft JSON
I mean then we're back to bloated strings over the network
nono you can use json.bson
i think
I actually can't tell if that namespace is part of the newtonsoft package
Or alternatively https://odininspector.com/odin-serializer
which is apparently the solution that Raft employed
Would have to distribute the DLL tho
From some cursory googling, BSON is not smaller in size
easy networking will come with tradeoffs, and we're talking in the megabyte range over the entire game session
people can always write their own to optimize for their objects if needed
Sounds like json would fit your standards then
newtonsoft's bson is deprecated since it was moved
understood
how do RPCs serialize then?
FastBufferReader/FastBufferWriter? are those marked as internal?
INetworkSerializable can be used
They use INetworkSerializable
but that would require people to know how to serialize their objects by hand
It's not too difficult though
aye. Maybe we could use INetworkSerializable's serialization/deserialization when available and fallback to JSON?
That would keep overheads minimal for primitives like string, vectors, etc
I mean I'm not sure if those are actually INetworkSerializable
Since they are defined by c# and unity themselves
ngo couldn't add that interface to them
NC4GO implements serializers/deserializers for primitives, yes
C# Primitive types will be serialized by built-in serialization code. These types include bool, char, sbyte, byte, short, ushort, int, uint, long, ulong, float, double, and string.
Yeah what I'm saying is how I can automatically detect whether or not it can be serialized like that
I can't just use is INetworkSerializable for those types
I can use that for custom classes
Type check ig
I mean at that point they can probably just make their own custom messages anyways lol
ideally it should remain a simple solution for users who just want quick networking
yeah the only slight pain is that if multiple mods bundle it then it's gonna end up being loaded from multiple dlls, unless someone makes it its own thunderstore package?
although I don't think theres many mods wanting to do this kinda thing
Sounds like a good idea
Licensed under Apache, so very chilling
I'm not familiar
You can use it commercially (earn money from derived works)
Basically all I would need to care for is distribution with license
which I should be able to do with apache
Sounds good right?
Raft wouldn't have been able to use it, otherwise, so yes
Yep
I would probably go with that
or newtonsoft
I wonder if I need to wrap primitive types
What's your thought process? Why'd you think you might need to?
Not with Odin I doubt
well in case you just wanna send like an int or something
Since right now it's limited to reference types as well
but I'm not too bothered
Does odin have a nuget package I wonder
they don't seem to
well I'd have to distribute it anyways
They don't make downloading this easy lmao
It seems to be a unity package
not just a dll
Betting the unity package just has a dll in it lol
Yeah I'm gonna see
their little download tool makes you give it a custom namespace lmao
If you intend to include OdinSerializer in one of your own product distributions, you should modify all source files using a tool like search and replace to move the OdinSerializer namespace into an appropriate namespace for your project, and rename the .dll's that are built. This is to avoid namespace and assembly conflicts in the cases where multiple different assets in the same project all use possibly differing versions of OdinSerializer. For example, you might globally rename "OdinSerializer" to "MyProject.Internal.OdinSerializer", and also have the .dll's renamed to "MyProject.Internal.OdinSerializer.dll".
so could write an MSBuild task to download source code from their GitHub, fix the namespaces, etc
hmm
It's a bunch of C# files
once I've finished the NetCode weave action and done the restructure
I can make an automatic thing for generating a thunderstore package, but not sure what to do about referencing that in project
Oh yeah we can just do it in our repo
I mean I could just copy the unitypackage's cs files into the repo since I gave them the LC_API namespace lol
I'm actually not sure if apache allows that specifically
or just redistributing the binaries
but they don't actually provide binaries
technically the unitypackage would just be compiled in the assembly csharp
I would use the cs files from their GitHub if possible
not sure if they'll be different
those cs files have improper namespaces, don't they?
Oh it's just odin serializer?
Yeah
I wonder if I can build the project on github into its own dll and just use that
you can, but that can cause namespace issues if other people do the same thing
Regardless I do have it working with newtonsoft atm
well I'd have to manually change all the namespaces if I put it in the plugin then
Okay awesome. let's stick with that and I'll open an enhancement issue for later
which is what their download tool did for me I think
The "we'll fix it in post" of game dev xD
It pains me that there has to be a security vulnerability in creating a byte array from what is literally just a bunch of bytes 😢
Just let me mem copy the entire thing
jesus christ that was an ordeal
@jagged trout it is done
https://github.com/Lordfirespeed/setup-netcode-weaver/blob/main/src/lib/target-framework-moniker.ts is the brunt of what I had to do 😭
but anyway, it works
https://github.com/u-2018/LC-API/pull/52 is no longer a draft (thankyou for marking it so)
Should there be a slash here or no?
There was previously and I removed it because SolutionDir has a / on the end
No idea why
interesting
Should I make the network messages need to be manually registered like harmony patches?
It'd be static though so you could just like Network.RegisterAll() and there'd also be the one for registering messages inside a specific type like: Network.RegisterAll(type) to mirror harmony's PatchAll
Yes
Ideally with the same API as harmony
Actually, that's only really valid if it's possible to 'unregister' network messages
it is
okay, then yeah
it would be good to let people unregister their messages as a 'teardown' thing
of course adoption would be low (almost no one implements teardown) but its a shame because implementing teardown allows hot-reloading
cant wait for this 🙏
From this point on main will be frozen to releases/release candidates
Hang on, before you do that
all future PRs should target dev
let me fix the Thunderstore folder
I already did, but what's up
well I haven't done any releasing yet
the dev branch is still synced
where were you gonna put it?
I'm going to remove the unnecessary duplicated assets (README) and make the paths nicer because tcli does the path remapping for us
didn't seem to do anything
I'll probably just reclone
actually the sync button on github might work
yeah cool, that worked
yeah @jagged trout there are a few options for that
- keeping your
mainbranch clean on your fork so it can always sync git remote add upstream ...and thengit pull upstream main
yeah I have upstream, for some reason updating it kept my local files plus your changes
but syncing on github then pulling seemed to work
That might be a git.config issue to do with preventing the possibility of all local copies being purged
if a remote repo gets compromised
FYI if you set this in your csproj.user then dotnet build will automatically build the mod zip, provided you have tcli installed
<PACK_THUNDERSTORE>true</PACK_THUNDERSTORE>
dotnet tool install -g tcli
so where's the thunderstore readme at now?
It gets copied from the repo readme
hm
Oh, were they different?
we also need the network bundle
where's it at?
because of the rule in assets/thunderstore.toml
can you move the "versions" stuff from the thunderstore readme to CHANGELOG.md and include that in the thunderstore?
since thunderstore has a changelog page
if it's there
Yeah, that sounds like a good solution. Then we don't need two separate readmes, rght?
I'll use the Keep A Changelog format if that's ok
just this:
# Features
AssetBundle loading - Put asset bundles in BepInEx > Bundles and load them using BundleAPI.BundleLoader.GetLoadedAsset
ServerAPI - Utilities relating to the network and server. This includes:
ModdedServer - Automatically alerts other users when you host a server that your server is modded.
It also lets mod authors make their mods put users in special matchmaking where they can only play with other modded users
Networking - Easily send data across the network to sync data between clients
Aye, in that case the root readme has parity
Yeah then just get the versions into changelog.md and I'm gonna reformat it then I can merge
i'm already reformatting it 😅
I'm pretty sure we have the same idea
I would like new versions to be at the top
already done
yeah that's what I use mainly
as long as Bundles folder resides next to the dll when r2modman unpacks it, I'm cool with it
yeah I think that'll happen using that path
though I would potentially consider moving the dll to the plugins folder just for those manual installers that drag and drop the BepinEx folder
I've had like 8 issues opened about manual installation because none of them know how to set it up
so I made it as easy as possible
#32, #42, #45, #46, #48, #51
all of these issues were because people just dragged and dropped files and expected it to work
lmao
and then complain when filename collisions mean that nothing works right
so in the next version I have it just look exactly where the dll is for the Bundles folder
or that they didn't copy the right file in the first place, like this situ
Nah the issue was I was looking specifically for 2018-LC_API
which manual installation doesn't have
I didn't know PluginInfo.Location existed
so I was going off of Paths.PluginPath
¯_(ツ)_/¯
it's "fixed" in the next version though
Paths.PluginPath should be accurate
the problem is people installing manually and not using BepInEx correctly
Nah that's BepinEx/plugins
ah sorry, you're right
PluginInfo.Location is the literal location of the dll of the plugin lol
Now I just do Path.Combine(Plugin.Instance.Info.Location.Substring(0, Plugin.Instance.Info.Location.LastIndexOf(Path.DirectorySeparatorChar)), "Bundles", "networking")
https://github.com/u-2018/LC-API/issues/49 this one is funny since he solved it before I even managed to see it
Path.GetDirectoryName(Info.Location)
sorry 😅
if you're within the plugin class, that is
otherwise
wdym transpilers @jagged trout ?
Path.GetDirectoryName(Plugin.Instance.Info.Location)
I've been doing a whole bunch of filepath bullshit to get the Dehumidifier working. So it's fresh in my memory, haha
of course, I confused myself a few times -
GetDirectoryName("foo/bar/abc") returns "foo/bar" which is obvious, but if abc is a directory you wouldn't initially think to do GetFileName to get the abc part
^-^ I made this a few years back https://github.com/NicholasScott1337/SmartBepInMods/tree/master/Tools
oh you're back!
hello
yeah @jagged trout https://github.com/u-2018/LC-API/pull/58 is ready for review
I was just about to test it
I mean not that there's much to test
true
You can also click on the checkmark and get a download of the Thunderstore mod .zip generated by the build action
I think
there should be 'Artifacts' -> build-artifacts.zip
the lc-api.version.zip will be inside that somewhere
It might be that only 2018 can
amazing version
yeah
the main branch ones will be more sane
I think I set it to increment the pre-release rather than the patch number
transpiling w/ bepinex was bad 2 years ago, I wonder if it's better now? like some opcodes just didn't show right and not always matching what dnspy showed for example?
73 is the number of commits since the last tag
ye, sooory ;~;
so if the commit is tagged 3.2.1 the version will be 3.2.1
if the 3rd commit back is tagged 3.2.1 the version will be 3.2.1-alpha.3
I just use harmony do add/remove code instructions as needed
you'll see it in my patches for the hurting and dying event
not sure why it's 0.73 though and not just 73
I just prefer events to be implemented with transpilers as they are the most compatible
some make sense as a prefix/postfix as well
but most need to go mid code
mystery
i don't understand how people can go 'hurr dee durr cancel original method every time' without worrying about compatability
Does this look like a reasonable overhead for "no netcode patching" RPCs?
I don't know 🤔
what I do know is netcode patching isn't difficult to configure
but i do understand it's really annoying
I'm not sure whether unpatched RPCs can work at all
are you imitating what the patcher inserts in ValidateRPCExecution?
These do
Yeeee ;~;
if you're trying to make it a library
you could use harmony to runtime patch their RPCs
and add your validateRPCExecution automatically
then your thing would be identical to netcode for gameobjects RPCs, right?
you would need to write a way for other mods to ask your mod 'Hey, please patch my RPCs!!'
so that you don't start runtime patching methods that have already been patched by Netcode weaver
How would I get assembly references to other loaded mods w/o them passing me an Assembly.GetExecutingAssembly()?
what do you need them for?
Cuz I culd just do a single attribute like [Nyetwork] applied ot the NetworkBehaviour
oh
Then just patch all those
I wouldn't do it that way
if you look in Harmony's sourcecode
You can see the implementations for patch discovery
You're basically trying to do the same thing as that
It's a lot of code
I would probably do something like PatchMyNetworkBehaviour<NetworkBehaviour>();
public static void PatchMyThing<T>() where T : NetworkBehaviour
{
}
which users would call in their Plugin.Awake()
@jagged trout I have a bone to pick with you
public IEnumerator PlaylistCoroutine()
{
PrepareNextSongInPlaylist();
while (Boombox.boomboxAudio.isPlaying) yield return new WaitForSeconds(1);
IncrementPlaylistIndex();
}
what the fuck is that
no, youtube boombox
I'm forking it to make something even more rudimentary
I use that to detect when the song is over to play the next song
Yes
My plan is to delete that whole boombox controller
and let 'sound pack' creators add tracks using JSON files
which are downloaded when the game opens
no more copyright problems
it can download the audio straight to (other) Steven's boombox tracks folder
Yeah I want to make the ui for yt boombox better at some point
but I haven't worked on it in a while
yeah I've already removed the UI from the fork 😅 since I'm going for config-only
I also suck at UI design.
Lmaoo that's ok
Same
I love working with people that actually enjoy/know graphic design
I helped make that iteration of the website, I did most of the splash area
but jesus I could never have designed it
Harmony might be the most cursed C# project tbh
😂😂😂😂
using a stack trace to get the calling assembly lmao idk any other way so I just used that
I don't think so
well not always
that would get the current assembly
We need to get the one that called the method
oh
@unique sluice this is what you wanted
I needed the exact same thing to search all their types for NetworkMessage annotations lol
weird
If only there was some sorta guide on manual installation for the current version
lmao
Also
I think I'm gonna release 3.2.0 today so that this issue can go away and we can get the networking out
I'll just keep my events for the next version
Now time to find what my changes are so I can update the changelog
Wait I think it was literally just networking and your project restructure right @main minnow ?
should I even put that in the changelog?
it just probably wouldn't matter to devs/users I don't think since they won't usually be interacting with it at all other than seeing the build checks
hm
idek what I'd put in there for it lmao
This mod causes issues joining into regular servers
LC API will prevent you from joining regular servers at another mod's request
it will not prevent you from joining regular servers without another mod telling it to do so
ex
alright well, I want to use the Coroner mod but thats with LC API
@main minnow you wouldn't happen to know how to merge tags from a fork would you?
git pull --tags [fork]
git push --tags [origin]

I can push them to my fork
that's the only way to do it
but I can't get them to the actual main repo
we should just start working out of your fork lmao
(no, 2018 just needs to give you the right permissions ...)
Well I don't want to take the project from them
They quite literally don't want it
There's a reason for this:
@balmy rover
it was previously '2018 HATES lethal company modding'
it would be best if they handed over the Thunderstore team to you so we can keep using the front-page project
The main issue is if we were to move it to a different team, we probably wouldn't ever get recognized because LC API is the most downloaded mod... It would be seen as a knockoff or potentially even as malware. I also think the thunderstore mods would delete it for being a "copy"
So moving it to a new team is basically out of the question
This
People do not care if the GitHub repo moves or whatever
and NuGet doesn't exist yet
So the only thing that would need to happen is that ^^
I think all they have to do is set you as 'owner'
@jagged trout
I mean, all we actually need is an API key for the team
Yeah
wait
lmao one sec
nvm lmao
I thought I had accidentally bypassed the security somehow
😂
All I did was go to https://thunderstore.io/settings/teams/2018/add-service-account/
kek
and it had the menu, but when I tried to add it, it just ignored it
ye i would message 2018 and ask if you can be set as owner
if no, just a service account would be perfect
ill probably come back at some point so i just added them as a service account
gamedev requires 100% of my time so once i eventually finish this project i might start working on mods for a little while again
(and its not like i dont want this project, just other stuff is getting in the way of me working on this (and i got burnt out from working on mods all the time))

sweet! we'll work out of https://github.com/steven4547466/LC-API until such a time as you return
Thanks to @main minnow after a few versions of testing (sorry) we now have publish workflow that will auto upload the package to thunderstore and nuget
Speaking of nuget, you can now reference the package from there! https://www.nuget.org/packages/LethalCompany.LC-API
This should streamline development as well as provide the XML docs for you when you use it while I work on actual documentation (eventually™️)
That's some high tech stuff O.o
I've been receiving issue reports that LC_API makes their clients no longer work with vanilla clients. I don't know if this is a known issue or can be resolved but whenever I try to make LC_API a dependency I get numerous calls to remove it.
They dont use LC API anymore on newest update. Check Coroner again
Oh i just got the one where it said it doesnt use lc api lol
Yeah I believe it's due to the player networking bundle causing network configs to be out of sync
I'm thinking of ways around it, but since the player class needs to be networked I'm not entirely sure what I can do at the moment
I don't really get the appeal of playing with different modlists?
considering LC API provides both client and server sided things I'm not sure it's even feasible to provide the ability to use it without everyone in the lobby needing it
same with any other mod that needs a custom network prefab
@jagged trout i could be doing this wrong but it seems broadcasting a message is host only even tho it says ANYONE can send them
or atleast very inconsistent if it sends it or not
@main minnow and I have tested clients sending and it seemed to have worked, can you show me your code?
and are there any errors?
@cyan trout ^
Also, my Internet just got turned off, so this might have to wait a few days
Depends on if I can convince Xfinity to turn it back on until my next paycheck
public class ReviveMessage
{
public int PlayerId { get; set; }
}
public static void BroadcastRevive(int playerId)
{
Debug.LogWarning("BroadcastRevive");
Debug.LogWarning(playerId);
Network.Broadcast("VIVIKO_REVIVE", new ReviveMessage() { PlayerId = playerId });
}
[NetworkMessage("VIVIKO_REVIVE", true)]
public static void ReviveHandler(ulong sender, ReviveMessage message)
{
Debug.LogWarning("ReviveHandler");
Debug.LogWarning(message);
Debug.LogWarning(message.PlayerId);
}```
serveral time i tested this and 90% of the time when the non host triggers the broadcast it doesnt send ot the host/everyone else
I'll test it on LAN since I don't have internet atm
Yeah I just sent 100 and received 100
Exact same code
Hm
It's sent with ReliableSequnced, so unity netcode should be ensuring it sends
I wonder if the issue is on the receiving relay
Did you happen to leave and join multiple games?
Specifically whoever was hosting
Since the host serves the relay
The only thing I could think of is somehow the host isn't relaying the message
testing:
match 1:
host kills client and triggers this - works
client kills host- works
match 2:
client kills host - doesnt work
What do you mean by "match 2" like second day?
Or quitting out of the server and making a new one
quit that match and hosted another
iiinteresting
That is weird
I do have to unregister the relay and all messages when the server is exited because the network is off, but I did ensure messages were re-registered when a new server was started. I'll have to check that the relay is, too.
It's weird that it'd work sometimes though
Because that would lead me to assume everything is properly registered
Seems like hes still gone…
?
@jagged trout are u about?
Could u merge a PR and make a release?
The nuget package is auto referencing gamelibs which is annoying for my dev workflow
done for 3.2.3
Woohoo!
oh it's a race condition
in MSBuild
where NetcodePatcher is being executed twice at the same time
rerun the task
seems to be working
basically when we MSBuild it uses only 1 process
but Github actions runners set a higher process count by default
Which means sometimes it's running NetCode weaver 2x in parallel
and that would be fine except it means they are both accessing the same logfile
apparently there's an issue with large network messages where it goes beyond buffer size and needs to be fragmented
oh crikey
I need to ensure the fragmented channel doesn't interfere with anything
unity has built in fragmentation transport, but I need to make sure the relay doesn't mess up
Did you have a chance to investigate network messages originating from clients working intermittently?
Not just yet
I'll create an issue so that I don't forget
Also I was kept at work for an extra 2 hours today so I am absolutely out of energy
Good plan
Oooooofff
so I will probably not be able to get to these until either tonight or sometime tomorrow
Like I said though I'm assuming this one has to do with the relay not being properly re-registered when creating a new game
In here at the moment: https://github.com/steven4547466/LC-API/blob/main/LC-API/Networking/Network.cs#L329-L373
I planned to move them to their own methods
so I could unregister the event handler for hot reloading
but atm that's a far in the future plan
but basically, since the network manager turns off when leaving a game, you have to unregister all the messages
then keep re-register them when a new game is joined or (if you're the host) also the relay
wait
I know exactly why
when I unregister them I remove the handler
so it doesn't re-register on new game join
pain
well it was an easy fix
just added a param for whether or not to actually fully remove it
and with that I'm dead for about 2-3 hours
I'll test it then
alright
just tested main and my local changes on dev
didn't work on main, worked on dev
pretty sure that's fixed
now to see if fragmented has problems
Awesome!
Ok and fragmented sequenced seems to just work drag and drop
tested it before and after with 1000 randomly generated random length strings
failed on reliablesequenced, worked on reliablefragmentedsequenced
noice
Also I added a vanilla support config option, however, it disables the entire player and item class
including related events
which makes the API generally useless
it would have its Networking still since those don't require synchronization, except the host requires the mod to relay
the message would just be ignored on clients that don't have LC API
So I'm debating whether or not we should even have it
because technically if one player has LC API, the rest are gonna need it for the API to even work
So I'm heavily debating whether or not I should even add vanilla support
LC API is just a server sided mod now basically
right I see what you're saying
what about asset bundle loading?
since thats what basically all of these clientside mods were using lc api for
Nope, using netcode weaver
what the fuck
i'm so confused
ohhh
never mind
i understand
okay i need to add csproj tasks for netcode weaving then...
muh
hwuheehhe
you're lucky i've done this before
well, when you're back
@main minnow your PR build fails
What is the difference anyways?
ok
I was gonna go to bed
When I wake up tomorrow I'm gonna test the dev branch make sure there's no problems then release
but I am very tired
You know
I could technically set up the Player behaviour to use custom network messages...
seems very silly, though
since they work in a static context, I'll have to pass the player id along the message and get the actual player out on the receiving end
I do lose the ability to use NetworkVariables, though
Which I currently use to set the player's network id from the host to ensure they sync with clients and that all clients have proper IDs
Who is maintaining this now? I thought Bobbie took it for a while but I'm not sure
Okay, thanks
I think LC API is breaking my game
Yea don't use it
I removed it and never had a problem since

