Giter Club home page Giter Club logo

archipelago.multiclient.net's People

Contributors

alwaysintreble avatar berserker66 avatar caitsith2 avatar dariof4 avatar ijwu avatar jarno458 avatar sunnybat avatar thephar avatar toasterparty avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

archipelago.multiclient.net's Issues

Duplicates of the exact same item causes ItemHelper desyncs

I think I've tracked this down to a library issue.

When receiving exact copies of the same item from the exact same location, the produced NetItems compare identical. This causes ReceivedItemHelper:Socket_PacketReceived to skip the duplicate items -- preventing it from being added to the itemQueue, among other things.

The first time this happens, the client is never notified of the new item. The second time it happens, a resync triggers (since Multiclient realizes it only has N items in its list when it should have N+1) and from the caller'sperspective it receives two new items: the first two items ever sent. This behavior is witnessed with ArchipelagoMW-HollowKnight/Archipelago.HollowKnight#79.

This currently can only happen with /send, !getitem, and startinventory -- all of which can have multiple instances of the same item ID, sender, recipient, and location.

Log WebSocketSharp errors to somewhere... else...

I believe we can set up custom loggers in WebSocketSharp's WebSocket object. We should have it log somewhere other than stderr or wherever it currently goes since in Unity games that almost always ends up in the Unity player logs which is disparate from where other errors typically go (such as stdout, modloader logs, etc.).

We can possibly provide options to allow callers to provide their own loggers and then provide another NuGet package with logger implementations for things like BepInEx or Hollow Knight's ModdingApi, as examples.

GetDataPackage should use new Inclusions rather than outdated exclusions

Currently the Archipelago.MultiClient.Net still uses the old outdated GetDataPackage api, where you specificy which games to exclude from retrieval, this should be change to use the new api where you specify games to query

Optionally, there was a report on discord where a user ended up with a datapackage cache of 0 bytes and this resulted in a crash. we could add additional checks to prevent such crashes and invalidate the cache in such cases

Optionally 2, With an ever growing list of games, it begins to make sense to only load the cache of the games that are actually being played on the server. we instead of the datapackagecache.archipelagocache use a folder, with one file for each game in it with the version number in the filename, so we can avoid loading it into memory when the version does not match as we know we got to update it and at the same time we could selectively only load the games we need to server the current multiworld

Synchronous data retrievals from the DataStorage inside the websocket thread causes softlock

Using the data storage for Synchronous retrieval in code that runs on websocket thread will cause the thread to wait for a Retrieved packet, but that can never be processes as the thread itself is waiting

you can reproduce this with int x = session.DataStorage["A"] inside a session.Socket.PackedReceived() handler or other code that runs on the websocket thrread like session.Locations.CheckedLocationsUpdated() handler

A workaround is to use asynchronous retreivals in such case like session.DataStorage["A"].GetAsync(x => { })

I propose to add a max timeout to the synchronous retrieval and log and throw an error if this time is exceeded

Support full URL format as overload for creating sessions.

Should support taking in one URL string to attempt to parse.

Format is: [scheme][<user>[:<password>]@]<address>:<port>

If scheme is not provided or is not ws:// then it should be replaced with ws://. If user (and subsequently, optionally, password) is provided then perhaps we can cache that and allow for a streamlined connection process?

Expose GetDataPackage

As far as I can tell, the GetDataPackage API and the data it returns isn't exposed publicly anywhere in the high-level API, and as a consequence there's no way to get an item or location's name unless it's exactly the item you most recently received. It would be useful to have access to this information one way or another.

Flaky Unitests

The unit tests for the Data Storage are flaky as they regulairly hit the key retreival timeout
such error look like this:
Timed out retrieving data for key "Item". This may be due to an attempt to retrieve a value from the DataStorageHelper in a synchronous fashion from within a PacketReceived handler. When using the DataStorageHelper from within code which runs on the websocket thread then use the asynchronous getters. Ex: "DataStorageHelper["Item"].GetAsync().ContinueWith(x => {});" Be aware that DataStorageHelper calls tend to cause packet responses, so making a call from within a PacketReceived handler may cause an infinite loop.
Workaround: Generally re-run failed jobs on the PR will fix this issue

Archipelago.MultiClient.Net for .Net Framework 3.5 or Net Framework 4.0 does not support wss to AP

The versions for .Net Framework 3.5 or Net Framework 4.0 use https://github.com/sta/websocket-sharp
Websocket Sharp
this library is sort of the only option that is available for websockets that also work for unity games
Its widely used in various projects but also not really maintained and WSS support is currently broken

This might also be caused by supported TLS versions, especially for lower .net framework versions TLS support is limited
https://learn.microsoft.com/en-us/dotnet/framework/network-programming/tls

Location name encoding can get corrupted

When calling session.Locations.GetLocationNameFromId() for a location whose name is "CD: Siegbräu", I received instead "CD: Siegbr��u". I think maybe some part of the network/JSON infrastructure is losing the encoding information?

Invalid type error when creating session

I recently started working on Inscryption which uses .NET Standard 2.0 and I get this error when calling ArchipelagoSessionFactory.CreateSession:

Invalid type Archipelago.MultiClient.Net.Converters.ArchipelagoPacketConverter for instance field Archipelago.MultiClient.Net.Helpers.ArchipelagoSocketHelper:Converter
  at Archipelago.MultiClient.Net.ArchipelagoSessionFactory.CreateSession (System.String hostname, System.Int32 port) [0x00007] in <608ab731db5a4a4fabc8e725e7273242>:0
  at Archipelago_Inscryption.Archipelago.ArchipelagoClient.CreateSession () [0x00001] in <f39eb8b90aa64a5e967d32da2dda428e>:0

Version type deserialization broken in .NET Core 3.1

.NET Core 3.1 introduced a default type converter for the Version type. Serialization still works due to the NamedTupleInterchangeConverter mimicking the previous conversion semantics for serialization. However, there is no deserializer in .NET Core 3.1 which can deserialize a Version object which was serialized with the library. (So the lib can't talk to itself, how funny is that?)

Suggestion: we implement a custom Version class, finally, which meets the spec for AP and use that. Version object seems to have served its purpose and I'm only suggesting we replace it as a result of this issue.

Documentation

The example code presented in README.MD leaves first time users with some questions:

  • What does CompleteLocationChecks do? It might seem obvious, but I had to do a double take and look at an example client to know for sure.
  • What's the difference between CompleteLocationChecks and ScoutLocationsAsync?
  • The Item Helper example shows receivedItemsHelper.DequeueItem(), but does not hint to the reader as to what information within the dequeued object might be useful. What is a client responsible for doing with this info?
  • Will the received items helper callback be invoked after a fresh connection for the first batch of remote items?

A minimalistic example class with connection error handling, basic message handler, basic item received callback, and a "report location completion" function would go a long way to helping new devs.

.NET 3.5 OnMessageReceived Errors

  1. The .NET 3.5 distribution of MultiClient.Net does not report System.Drawing.dll as a dependency, causing this runtime error:
[Info   :   Console] 9/1/2022 9:33:06 AM|Error|WebSocket.messagec:0|System.IO.FileNotFoundException: Could not load file or assembly 'System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies.
                          File name: 'System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
                            at Archipelago.MultiClient.Net.Helpers.MessageLogHelper.Socket_PacketReceived (Archipelago.MultiClient.Net.ArchipelagoPacketBase packet) [0x00000] in <filename unknown>:0
                            at (wrapper delegate-invoke) Archipelago.MultiClient.Net.Helpers.ArchipelagoSocketHelperDelagates/PacketReceivedHandler:invoke_void__this___ArchipelagoPacketBase (Archipelago.MultiClient.Net.ArchipelagoPacketBase)
                            at (wrapper delegate-invoke) Archipelago.MultiClient.Net.Helpers.ArchipelagoSocketHelperDelagates/PacketReceivedHandler:invoke_void__this___ArchipelagoPacketBase (Archipelago.MultiClient.Net.ArchipelagoPacketBase)
                            at Archipelago.MultiClient.Net.Helpers.ArchipelagoSocketHelper.OnMessageReceived (System.Object sender, WebSocketSharp.MessageEventArgs e) [0x00000] in <filename unknown>:0
                            at WebSocketSharp.Ext.Emit[MessageEventArgs] (System.EventHandler`1 eventHandler, System.Object sender, WebSocketSharp.MessageEventArgs e) [0x00000] in <filename unknown>:0
                            at WebSocketSharp.WebSocket.messagec (WebSocketSharp.MessageEventArgs e) [0x00000] in <filename unknown>:0
  1. This error:
[Info   :   Console] 9/1/2022 10:24:41 AM|Error|WebSocket.messagec:0|System.InvalidProgramException: Invalid IL code in System.Drawing.Color:get_White (): method body is empty.

                             at Archipelago.MultiClient.Net.Helpers.MessagePart..ctor (MessagePartType type, Archipelago.MultiClient.Net.Models.JsonMessagePart messagePart, Nullable`1 color) [0x00000] in <filename unknown>:0
                             at Archipelago.MultiClient.Net.Helpers.MessageLogHelper.GetMessagePart (Archipelago.MultiClient.Net.Models.JsonMessagePart part) [0x00000] in <filename unknown>:0
                             at System.Linq.Enumerable+<CreateSelectIterator>c__Iterator10`2[Archipelago.MultiClient.Net.Models.JsonMessagePart,Archipelago.MultiClient.Net.Helpers.MessagePart].MoveNext () [0x00000] in <filename unknown>:0
                             at System.Collections.Generic.List`1[Archipelago.MultiClient.Net.Helpers.MessagePart].AddEnumerable (IEnumerable`1 enumerable) [0x00000] in <filename unknown>:0
                             at System.Collections.Generic.List`1[Archipelago.MultiClient.Net.Helpers.MessagePart]..ctor (IEnumerable`1 collection) [0x00000] in <filename unknown>:0
                             at System.Linq.Enumerable.ToArray[MessagePart] (IEnumerable`1 source) [0x00000] in <filename unknown>:0
                             at Archipelago.MultiClient.Net.Helpers.MessageLogHelper.GetParsedData (Archipelago.MultiClient.Net.Packets.PrintJsonPacket packet) [0x00000] in <filename unknown>:0
                             at Archipelago.MultiClient.Net.Helpers.MessageLogHelper.TriggerOnMessageReceived (Archipelago.MultiClient.Net.Packets.PrintJsonPacket printJsonPacket) [0x00000] in <filename unknown>:0
                             at Archipelago.MultiClient.Net.Helpers.MessageLogHelper.Socket_PacketReceived (Archipelago.MultiClient.Net.ArchipelagoPacketBase packet) [0x00000] in <filename unknown>:0
                             at (wrapper delegate-invoke) Archipelago.MultiClient.Net.Helpers.ArchipelagoSocketHelperDelagates/PacketReceivedHandler:invoke_void__this___ArchipelagoPacketBase (Archipelago.MultiClient.Net.ArchipelagoPacketBase)
                             at (wrapper delegate-invoke) Archipelago.MultiClient.Net.Helpers.ArchipelagoSocketHelperDelagates/PacketReceivedHandler:invoke_void__this___ArchipelagoPacketBase (Archipelago.MultiClient.Net.ArchipelagoPacketBase)
                             at Archipelago.MultiClient.Net.Helpers.ArchipelagoSocketHelper.OnMessageReceived (System.Object sender, WebSocketSharp.MessageEventArgs e) [0x00000] in <filename unknown>:0
                             at WebSocketSharp.Ext.Emit[MessageEventArgs] (System.EventHandler`1 eventHandler, System.Object sender, WebSocketSharp.MessageEventArgs e) [0x00000] in <filename unknown>:0
                             at WebSocketSharp.WebSocket.messagec (WebSocketSharp.MessageEventArgs e) [0x00000] in <filename unknown>:0

AllLocationsChecked on LocationCheckHelper does not respect server's location_checked

AllLocationsChecked on LocationCheckHelper is only filled with the locations the game reports as checked by calling CompleteLocationChecks or CompleteLocationChecksAsync, however the initial value of locations_checked that is send on the connect package is not taken into account, neither are the updated values of locations_checked as part of RoomUpdated packages. As a result of this, !collect or coop is not properly taken into account

Bug: Session.Items.AllItemsReceived occasionally appears to append a null item

Occasionally AllItemsReceived has a null item appended to it, preventing clients that attempt to update their received items by reading this collection from getting the actual item, while they update their internal index. Unknown what exactly causes the issue, only know that manually tracking received items in the game client and occasionally verifying it against the lib collection would trigger them to be mismatched, despite the index being the same.

Exception when retrievieng location name from id

Exception when trying to retrieve item name through session.Locations.GetLocationNameFromId(locationName);
Iterating through location ID's does not result in an error. Checked the spoiler log and there were no locations with the same id.

Exception in IL2CPP-to-Managed trampoline, not passing it to il2cpp: System.ArgumentException: An item with the same key has already been added. Key: 257
  at System.Collections.Generic.Dictionary2[TKey,TValue].TryInsert (TKey key, TValue value, System.Collections.Generic.InsertionBehavior behavior) [0x000dd] in <986ed57b9a8f4699a3c59a69eb05944a>:0 
  at System.Collections.Generic.Dictionary2[TKey,TValue].Add (TKey key, TValue value) [0x00000] in <986ed57b9a8f4699a3c59a69eb05944a>:0 
  at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement] (System.Collections.Generic.IEnumerable1[T] source, System.Func2[T,TResult] keySelector, System.Func2[T,TResult] elementSelector, System.Collections.Generic.IEqualityComparer1[T] comparer) [0x0009e] in <c8122f496f05432baca55ffb7d139a58>:0 
  at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement] (System.Collections.Generic.IEnumerable1[T] source, System.Func2[T,TResult] keySelector, System.Func2[T,TResult] elementSelector) [0x00000] in <c8122f496f05432baca55ffb7d139a58>:0 
  at Archipelago.MultiClient.Net.Helpers.LocationCheckHelper.GetLocationNameFromId (System.Int32 locationId) [0x0006b] in <17d96186d9fe43bbb3a20afc3fa3c45d>:0 
  at TunicRandomizer.TunicArchipelagoClient.TunicArchipelagoClient.Connect (System.String host, System.Int32 port, System.String player, System.String password) [0x0013b] in <69b91c7de2bc4ae291624c6da21b8154>:0 
  at TunicRandomizer.Patches.MenuPatches+<>c.<pushDefault_OptionsPatch>b__11_1 () [0x00042] in <69b91c7de2bc4ae291624c6da21b8154>:0 
  at (wrapper dynamic-method) UnhollowerRuntimeLib.DelegateSupport.(il2cpp delegate trampoline) System.Void(intptr,UnhollowerBaseLib.Runtime.Il2CppMethodInfo*)

Datapackage is retreived to late

since the websockets packets are garenteed to preserver order it is highly recommended to requests updates for the data package before sending the connect request, this will ensure that the datapackage response is received before the connection result, and therefor if the connection is sucsesfull the datapackage will be processed before any received item packages

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.