diff --git a/Archipelago.MultiClient.Net.Tests/ArchipelagoSessionFixture.cs b/Archipelago.MultiClient.Net.Tests/ArchipelagoSessionFixture.cs
index 54edfdff..d6128257 100644
--- a/Archipelago.MultiClient.Net.Tests/ArchipelagoSessionFixture.cs
+++ b/Archipelago.MultiClient.Net.Tests/ArchipelagoSessionFixture.cs
@@ -193,8 +193,9 @@ static ArchipelagoSession CreateTestSession(IArchipelagoSocketHelper socket,
var roomState = new RoomStateHelper(socket, locations);
var dataStorage = new DataStorageHelper(socket, connectionInfo);
var messageLog = new MessageLogHelper(socket, itemInfoResolver, players, connectionInfo);
+ var createHints = new CreateHintsHelper(socket, players, locations, roomState);
- return new ArchipelagoSession(socket, items, locations, players, roomState, connectionInfo, dataStorage, messageLog);
+ return new ArchipelagoSession(socket, items, locations, players, roomState, connectionInfo, dataStorage, messageLog, createHints);
}
static void SetupLoginResultPacket(IArchipelagoSocketHelper socket, ArchipelagoPacketBase loginResultPacket) =>
diff --git a/Archipelago.MultiClient.Net/ArchipelagoSession.cs b/Archipelago.MultiClient.Net/ArchipelagoSession.cs
index c2442a48..8339940a 100644
--- a/Archipelago.MultiClient.Net/ArchipelagoSession.cs
+++ b/Archipelago.MultiClient.Net/ArchipelagoSession.cs
@@ -149,6 +149,9 @@ public partial class ArchipelagoSession : IArchipelagoSession
///
public IMessageLogHelper MessageLog { get; }
+ ///
+ public ICreateHintsHelper CreateHints { get; }
+
#if NET35
volatile bool awaitingRoomInfo;
volatile bool expectingLoginResult;
@@ -165,7 +168,8 @@ internal ArchipelagoSession(IArchipelagoSocketHelper socket,
IRoomStateHelper roomState,
ConnectionInfoHelper connectionInfoHelper,
IDataStorageHelper dataStorage,
- IMessageLogHelper messageLog)
+ IMessageLogHelper messageLog,
+ ICreateHintsHelper createHints)
{
Socket = socket;
Items = items;
@@ -175,6 +179,7 @@ internal ArchipelagoSession(IArchipelagoSocketHelper socket,
connectionInfo = connectionInfoHelper;
DataStorage = dataStorage;
MessageLog = messageLog;
+ CreateHints = createHints;
socket.PacketReceived += Socket_PacketReceived;
}
diff --git a/Archipelago.MultiClient.Net/ArchipelagoSessionFactory.cs b/Archipelago.MultiClient.Net/ArchipelagoSessionFactory.cs
index 8c45701d..bb6df8d7 100644
--- a/Archipelago.MultiClient.Net/ArchipelagoSessionFactory.cs
+++ b/Archipelago.MultiClient.Net/ArchipelagoSessionFactory.cs
@@ -21,14 +21,15 @@ public static ArchipelagoSession CreateSession(Uri uri)
var dataPackageCache = new DataPackageCache(socket);
var connectionInfo = new ConnectionInfoHelper(socket);
var players = new PlayerHelper(socket, connectionInfo);
- var itemInfoResolver = new ItemInfoResolver(dataPackageCache, connectionInfo);
- var locations = new LocationCheckHelper(socket, itemInfoResolver, connectionInfo, players);
+ var itemInfoResolver = new ItemInfoResolver(dataPackageCache, connectionInfo);
+ var locations = new LocationCheckHelper(socket, itemInfoResolver, connectionInfo, players);
var items = new ReceivedItemsHelper(socket, locations, itemInfoResolver, connectionInfo, players);
- var roomState = new RoomStateHelper(socket, locations);
- var dataStorage = new DataStorageHelper(socket, connectionInfo);
+ var roomState = new RoomStateHelper(socket, locations);
+ var dataStorage = new DataStorageHelper(socket, connectionInfo);
var messageLog = new MessageLogHelper(socket, itemInfoResolver, players, connectionInfo);
+ var createHints = new CreateHintsHelper(socket, players, locations, roomState);
- return new ArchipelagoSession(socket, items, locations, players, roomState, connectionInfo, dataStorage, messageLog);
+ return new ArchipelagoSession(socket, items, locations, players, roomState, connectionInfo, dataStorage, messageLog, createHints);
}
///
diff --git a/Archipelago.MultiClient.Net/Converters/ArchipelagoPacketConverter.cs b/Archipelago.MultiClient.Net/Converters/ArchipelagoPacketConverter.cs
index 7741aeae..4839554c 100644
--- a/Archipelago.MultiClient.Net/Converters/ArchipelagoPacketConverter.cs
+++ b/Archipelago.MultiClient.Net/Converters/ArchipelagoPacketConverter.cs
@@ -25,7 +25,8 @@ public class ArchipelagoPacketConverter : JsonConverter
[ArchipelagoPacketType.Connect] = obj => obj.ToObject(),
[ArchipelagoPacketType.ConnectUpdate] = obj => obj.ToObject(),
[ArchipelagoPacketType.LocationChecks] = obj => obj.ToObject(),
- [ArchipelagoPacketType.LocationScouts] = obj => obj.ToObject(),
+ [ArchipelagoPacketType.LocationScouts] = obj => obj.ToObject(),
+ [ArchipelagoPacketType.CreateHints] = obj => obj.ToObject(),
[ArchipelagoPacketType.StatusUpdate] = obj => obj.ToObject(),
[ArchipelagoPacketType.Say] = obj => obj.ToObject(),
[ArchipelagoPacketType.GetDataPackage] = obj => obj.ToObject(),
diff --git a/Archipelago.MultiClient.Net/Enums/ArchipelagoPacketType.cs b/Archipelago.MultiClient.Net/Enums/ArchipelagoPacketType.cs
index fe6c551e..ba362164 100644
--- a/Archipelago.MultiClient.Net/Enums/ArchipelagoPacketType.cs
+++ b/Archipelago.MultiClient.Net/Enums/ArchipelagoPacketType.cs
@@ -15,6 +15,7 @@ public enum ArchipelagoPacketType
ConnectUpdate,
LocationChecks,
LocationScouts,
+ CreateHints,
StatusUpdate,
Say,
GetDataPackage,
diff --git a/Archipelago.MultiClient.Net/Helpers/CreateHintsHelper.cs b/Archipelago.MultiClient.Net/Helpers/CreateHintsHelper.cs
new file mode 100644
index 00000000..00ec6772
--- /dev/null
+++ b/Archipelago.MultiClient.Net/Helpers/CreateHintsHelper.cs
@@ -0,0 +1,107 @@
+using Archipelago.MultiClient.Net.Enums;
+using Archipelago.MultiClient.Net.Packets;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Archipelago.MultiClient.Net.Helpers
+{
+ ///
+ /// Provides information about the current state of the server
+ ///
+ public interface ICreateHintsHelper
+ {
+ ///
+ /// Tell the server to create hints for the specified locations.
+ /// When creating hints for another slot's locations, the packet will fail if any of those locations do not contain an item for the requesting slot.
+ /// When creating hints for your own slot's locations, non-existing locations will be silently skipped.
+ ///
+ ///
+ /// The ID of the player whose locations ar ebeing hinted for.
+ ///
+ ///
+ /// If included, sets the status of the created hints to this status.
+ /// Defaults to unspecified.
+ ///
+ ///
+ /// The location ids to create hints for.
+ ///
+ ///
+ /// The websocket connection is not alive.
+ ///
+ void CreateHints(int player, HintStatus hintStatus = HintStatus.Unspecified, params long[] ids);
+
+ ///
+ /// Tell the server to create hints for the specified locations.
+ /// This version does not include the player id, and as such will only hint for locations in the active player's game.
+ /// When creating hints, non-existing locations will be silently skipped.
+ ///
+ ///
+ /// If included, sets the status of the created hints to this status.
+ /// Defaults to unspecified.
+ ///
+ ///
+ /// The location ids to create hints for.
+ ///
+ ///
+ /// The websocket connection is not alive.
+ ///
+ void CreateHints(HintStatus hintStatus = HintStatus.Unspecified, params long[] ids);
+ }
+
+ ///
+ public class CreateHintsHelper : ICreateHintsHelper
+ {
+ readonly IArchipelagoSocketHelper socket;
+ readonly ILocationCheckHelper locationCheckHelper;
+ readonly IRoomStateHelper roomStateHelper;
+ readonly IPlayerHelper players;
+
+ ///
+ public Version Version { get; private set; }
+
+ internal CreateHintsHelper(IArchipelagoSocketHelper socket, IPlayerHelper players, ILocationCheckHelper locationCheckHelper, IRoomStateHelper roomStateHelper)
+ {
+ this.socket = socket;
+ this.players = players;
+ this.locationCheckHelper = locationCheckHelper;
+ this.roomStateHelper = roomStateHelper;
+ }
+
+ ///
+ public void CreateHints(int player, HintStatus hintStatus = HintStatus.Unspecified, params long[] ids)
+ {
+ // The server supports CreateHints after version 0.6.2
+ if (roomStateHelper.Version.CompareTo(new Version(0, 6, 2)) <= 0)
+ {
+ CreateHintsFallback(ids);
+ }
+ else
+ {
+ socket.SendPacket(new CreateHintsPacket
+ {
+ Locations = ids,
+ Player = player,
+ Status = (int)hintStatus
+ });
+ }
+ }
+
+#if NET35
+
+ ///
+ public void CreateHintsFallback(params long[] ids) => locationCheckHelper.ScoutLocationsAsync(null, createAsHint: true, ids);
+#else
+ ///
+ public void CreateHintsFallback(params long[] ids) => locationCheckHelper.ScoutLocationsAsync(createAsHint: true, ids);
+#endif
+
+ ///
+ public void CreateHints(HintStatus hintStatus = HintStatus.Unspecified, params long[] ids)
+ {
+ // When the player is not included, it defaults to the requesting slot.
+ var currentPlayer = players.ActivePlayer.Slot;
+ CreateHints(currentPlayer, hintStatus, ids);
+ }
+ }
+}
diff --git a/Archipelago.MultiClient.Net/Helpers/LocationCheckHelper.cs b/Archipelago.MultiClient.Net/Helpers/LocationCheckHelper.cs
index 9780417f..f7c56059 100644
--- a/Archipelago.MultiClient.Net/Helpers/LocationCheckHelper.cs
+++ b/Archipelago.MultiClient.Net/Helpers/LocationCheckHelper.cs
@@ -413,7 +413,7 @@ LocationChecksPacket GetLocationChecksPacket() =>
#if NET35
///
- public void ScoutLocationsAsync(Action> callback = null,
+ public void ScoutLocationsAsync(Action> callback = null,
HintCreationPolicy hintCreationPolicy = HintCreationPolicy.None, params long[] ids)
{
var idsToScout = ids.Where(i => allLocations.Contains(i)).ToArray();
diff --git a/Archipelago.MultiClient.Net/Packets/CreateHintsPacket.cs b/Archipelago.MultiClient.Net/Packets/CreateHintsPacket.cs
new file mode 100644
index 00000000..c1ed4081
--- /dev/null
+++ b/Archipelago.MultiClient.Net/Packets/CreateHintsPacket.cs
@@ -0,0 +1,19 @@
+using Archipelago.MultiClient.Net.Enums;
+using Newtonsoft.Json;
+
+namespace Archipelago.MultiClient.Net.Packets
+{
+ public class CreateHintsPacket : ArchipelagoPacketBase
+ {
+ public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.CreateHints;
+
+ [JsonProperty("locations")]
+ public long[] Locations { get; set; }
+
+ [JsonProperty("player")]
+ public int Player { get; set; }
+
+ [JsonProperty("status")]
+ public int Status { get; set; }
+ }
+}