Skip to content

Commit 01b9f3b

Browse files
committed
feat: Add support for broadcasts
1 parent c626bfb commit 01b9f3b

File tree

6 files changed

+442
-1
lines changed

6 files changed

+442
-1
lines changed

Runtime/Client/LootLockerEndPoints.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,10 @@ public class LootLockerEndPoints
330330
public static EndPointClass ListNotifications = new EndPointClass("notifications/v1", LootLockerHTTPMethod.GET);
331331
public static EndPointClass ReadNotifications = new EndPointClass("notifications/v1/read", LootLockerHTTPMethod.PUT);
332332
public static EndPointClass ReadAllNotifications = new EndPointClass("notifications/v1/read/all", LootLockerHTTPMethod.PUT);
333+
334+
// Broadcasts
335+
[Header("Broadcasts")]
336+
public static EndPointClass ListBroadcasts = new EndPointClass("broadcasts/v1", LootLockerHTTPMethod.GET);
333337
}
334338

335339
[Serializable]

Runtime/Game/LootLockerSDKManager.cs

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8270,7 +8270,94 @@ public static void MarkNotificationsAsRead(string[] NotificationIds, Action<Loot
82708270
LootLockerServerRequest.CallAPI(forPlayerWithUlid, LootLockerEndPoints.ReadNotifications.endPoint, LootLockerEndPoints.ReadNotifications.httpMethod, LootLockerJson.SerializeObject(new LootLockerReadNotificationsRequest{ Notifications = NotificationIds }), (response) => { LootLockerResponse.Deserialize(onComplete, response); });
82718271
}
82728272
#endregion
8273-
8273+
8274+
#region Broadcasts
8275+
/// <summary>
8276+
/// List broadcasts for this game with default localisation and pagination settings
8277+
/// </summary>
8278+
/// <param name="onComplete">Delegate for handling the server response</param>
8279+
/// <param name="forPlayerWithUlid">Optional : Execute the request for the specified player. If not supplied, the default player will be used.</param>
8280+
public static void ListTopBroadcasts(Action<LootLockerListBroadcastsResponse> onComplete, string forPlayerWithUlid = null)
8281+
{
8282+
if (!CheckInitialized(false, forPlayerWithUlid))
8283+
{
8284+
onComplete?.Invoke(LootLockerResponseFactory.SDKNotInitializedError<LootLockerListBroadcastsResponse>(forPlayerWithUlid));
8285+
return;
8286+
}
8287+
8288+
LootLockerServerRequest.CallAPI(forPlayerWithUlid, LootLockerEndPoints.ListBroadcasts.endPoint, LootLockerEndPoints.ListBroadcasts.httpMethod, null, (response) => { LootLockerResponse.Deserialize(onComplete, response); });
8289+
}
8290+
8291+
/// <summary>
8292+
/// List broadcasts for this game with specified localisation and default pagination settings
8293+
/// </summary>
8294+
/// <param name="languages">Array of language codes to filter the broadcasts by. Language codes are typically ISO 639-1 codes (e.g. "en", "fr", "es") with regional variations (e.g. "en-US", "fr-FR"), but can also be custom defined by the game developer.</param>
8295+
/// <param name="onComplete">Delegate for handling the server response</param>
8296+
/// <param name="forPlayerWithUlid">Optional : Execute the request for the specified player. If not supplied, the default player will be used.</param>
8297+
public static void ListTopBroadcastsLocalized(string[] languages, Action<LootLockerListBroadcastsResponse> onComplete, string forPlayerWithUlid = null)
8298+
{
8299+
if (!CheckInitialized(false, forPlayerWithUlid))
8300+
{
8301+
onComplete?.Invoke(LootLockerResponseFactory.SDKNotInitializedError<LootLockerListBroadcastsResponse>(forPlayerWithUlid));
8302+
return;
8303+
}
8304+
8305+
string acceptLanguages = "";
8306+
if (languages != null && languages.Length > 0)
8307+
{
8308+
acceptLanguages = string.Join(",", languages);
8309+
}
8310+
var headers = new Dictionary<string, string>();
8311+
if (!string.IsNullOrEmpty(acceptLanguages))
8312+
{
8313+
headers.Add("Accept-Language", acceptLanguages);
8314+
}
8315+
LootLockerServerRequest.CallAPI(forPlayerWithUlid, LootLockerEndPoints.ListBroadcasts.endPoint, LootLockerEndPoints.ListBroadcasts.httpMethod, null, additionalHeaders: headers, onComplete: (response) => { LootLockerResponse.Deserialize(onComplete, response); });
8316+
}
8317+
8318+
/// <summary>
8319+
/// List broadcasts for this game
8320+
/// </summary>
8321+
/// <param name="languages">Array of language codes to filter the broadcasts by. Language codes are typically ISO 639-1 codes (e.g. "en", "fr", "es") with regional variations (e.g. "en-US", "fr-FR"), but can also be custom defined by the game developer.</param>
8322+
/// <param name="per_page">Used for pagination, this is the number of broadcasts to retrieve per page.</param>
8323+
/// <param name="page">Used for pagination, this is the page number to retrieve.</param>
8324+
/// <param name="onComplete">Delegate for handling the server response</param>
8325+
/// <param name="forPlayerWithUlid">Optional : Execute the request for the specified player. If not supplied, the default player will be used.</param>
8326+
public static void ListBroadcasts(string[] languages, int per_page, int page, Action<LootLockerListBroadcastsResponse> onComplete, string forPlayerWithUlid = null)
8327+
{
8328+
if (!CheckInitialized(false, forPlayerWithUlid))
8329+
{
8330+
onComplete?.Invoke(LootLockerResponseFactory.SDKNotInitializedError<LootLockerListBroadcastsResponse>(forPlayerWithUlid));
8331+
return;
8332+
}
8333+
8334+
var endpoint = LootLockerEndPoints.ListBroadcasts.endPoint;
8335+
8336+
var queryParams = new LootLocker.Utilities.HTTP.QueryParamaterBuilder();
8337+
if (per_page > 0)
8338+
queryParams.Add("per_page", per_page);
8339+
if (page > 0)
8340+
queryParams.Add("page", page);
8341+
8342+
endpoint += queryParams.Build();
8343+
8344+
string acceptLanguages = "";
8345+
if (languages != null && languages.Length > 0)
8346+
{
8347+
acceptLanguages = string.Join(",", languages);
8348+
}
8349+
var headers = new Dictionary<string, string>();
8350+
if (!string.IsNullOrEmpty(acceptLanguages))
8351+
{
8352+
headers.Add("Accept-Language", acceptLanguages);
8353+
}
8354+
LootLockerServerRequest.CallAPI(forPlayerWithUlid, endpoint, LootLockerEndPoints.ListBroadcasts.httpMethod, null, additionalHeaders: headers, onComplete: (response) => {
8355+
var internalResponse = LootLockerResponse.Deserialize<__LootLockerInternalListBroadcastsResponse>(response);
8356+
onComplete?.Invoke(new LootLockerListBroadcastsResponse(internalResponse));
8357+
});
8358+
}
8359+
#endregion
8360+
82748361
#region Misc
82758362

82768363
/// <summary>
Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
namespace LootLocker.Requests
5+
{
6+
//==================================================
7+
// Data Definitions
8+
//==================================================
9+
10+
/// <summary>
11+
/// Represents a publication setting for a broadcast message
12+
/// </summary>
13+
public class LootLockerBroadcastPublicationSetting
14+
{
15+
/// <summary>
16+
/// The time of publication
17+
/// </summary>
18+
public DateTime start { get; set; }
19+
/// <summary>
20+
/// The optional time of when the broadcast will no longer be returned
21+
/// </summary>
22+
public DateTime end { get; set; }
23+
/// <summary>
24+
/// The timezone that the start and end times are specified in, eg. UTC, Asia/Tokyo, or America/Washington
25+
/// </summary>
26+
public string tz { get; set; }
27+
};
28+
29+
public class __LootLockerInternalBroadcastLocalization
30+
{
31+
/// <summary>
32+
/// The key for this localization entry
33+
/// Some keys are system defined, eg. ll.headline, ll.body, ll.image_url, ll.action
34+
/// </summary>
35+
public string key { get; set; }
36+
/// <summary>
37+
/// The value for this localization entry
38+
/// </summary>
39+
public string value { get; set; }
40+
}
41+
42+
/// <summary>
43+
/// Represents a localised version of a broadcast message
44+
/// </summary>
45+
public class __LootLockerInternalBroadcastLanguage
46+
{
47+
/// <summary>
48+
/// The language code for this localised version of the broadcast message, eg. en-GB
49+
/// </summary>
50+
public string language_code { get; set; }
51+
/// <summary>
52+
/// Metadata associated with the localised version of this broadcast message
53+
/// </summary>
54+
public __LootLockerInternalBroadcastLocalization[] localizations { get; set; }
55+
};
56+
57+
/// <summary>
58+
/// Represents a localised version of a broadcast message
59+
/// </summary>
60+
public class LootLockerBroadcastLanguage
61+
{
62+
/// <summary>
63+
/// The language code for this localised version of the broadcast message, eg. en-GB
64+
/// </summary>
65+
public string language_code { get; set; }
66+
/// <summary>
67+
/// The headline for this broadcast message
68+
/// </summary>
69+
public string headline { get; set; }
70+
/// <summary>
71+
/// The body for this broadcast message
72+
/// </summary>
73+
public string body { get; set; }
74+
/// <summary>
75+
/// The image URL for this broadcast message
76+
/// </summary>
77+
public string image_url { get; set; }
78+
/// <summary>
79+
/// The action for this broadcast message
80+
/// </summary>
81+
public string action { get; set; }
82+
/// <summary>
83+
/// List of the keys available in the localizations dictionary
84+
/// </summary>
85+
public string[] localization_keys { get; set; }
86+
/// <summary>
87+
/// Localized entries for this broadcast message
88+
/// </summary>
89+
public Dictionary<string, string> localizations { get; set; }
90+
};
91+
92+
/// <summary>
93+
/// Represents a broadcast message
94+
/// </summary>
95+
public class __LootLockerInternalBroadcast
96+
{
97+
/// <summary>
98+
/// The unique identifier (ULID) for this broadcast message
99+
/// </summary>
100+
public string id { get; set; }
101+
/// <summary>
102+
/// The name of this broadcast message
103+
/// </summary>
104+
public string name { get; set; }
105+
/// <summary>
106+
/// A list of publication settings for this broadcast message
107+
/// This list will always contain at least the publication time in UTC, but may also contain additional publication settings for different timezones
108+
/// </summary>
109+
public LootLockerBroadcastPublicationSetting[] publication_settings { get; set; }
110+
/// <summary>
111+
/// Localised versions of this broadcast message
112+
/// </summary>
113+
public __LootLockerInternalBroadcastLanguage[] languages { get; set; }
114+
};
115+
116+
/// <summary>
117+
/// Represents a broadcast message
118+
/// </summary>
119+
public class LootLockerBroadcast
120+
{
121+
/// <summary>
122+
/// The unique identifier (ULID) for this broadcast message
123+
/// </summary>
124+
public string id { get; set; }
125+
/// <summary>
126+
/// The name of this broadcast message
127+
/// </summary>
128+
public string name { get; set; }
129+
/// <summary>
130+
/// A list of publication settings for this broadcast message
131+
/// This list will always contain at least the publication time in UTC, but may also contain additional publication settings for different timezones
132+
/// </summary>
133+
public LootLockerBroadcastPublicationSetting[] publication_settings { get; set; }
134+
/// <summary>
135+
/// The language codes available for this broadcast message
136+
/// eg. ["en", "en-US", "zh"]
137+
/// </summary>
138+
public string[] language_codes { get; set; }
139+
/// <summary>
140+
/// Localised versions of this broadcast message
141+
/// </summary>
142+
public Dictionary<string, LootLockerBroadcastLanguage> languages { get; set; }
143+
};
144+
145+
//==================================================
146+
// Response Definitions
147+
//==================================================
148+
149+
/// <summary>
150+
/// Response for listing broadcasts
151+
/// </summary>
152+
public class __LootLockerInternalListBroadcastsResponse : LootLockerResponse
153+
{
154+
/// <summary>
155+
/// A list of cronologically ordered broadcasts
156+
/// </summary>
157+
public __LootLockerInternalBroadcast[] broadcasts { get; set; }
158+
/// <summary>
159+
/// Pagination information for the request
160+
/// </summary>
161+
public LootLockerExtendedPagination pagination { get; set; }
162+
};
163+
164+
/// <summary>
165+
/// Response for listing broadcasts
166+
/// </summary>
167+
public class LootLockerListBroadcastsResponse : LootLockerResponse
168+
{
169+
/// <summary>
170+
/// A list of cronologically ordered broadcasts
171+
/// </summary>
172+
public LootLockerBroadcast[] broadcasts { get; set; }
173+
/// <summary>
174+
/// Pagination information for the request
175+
/// </summary>
176+
public LootLockerExtendedPagination pagination { get; set; }
177+
178+
public LootLockerListBroadcastsResponse()
179+
{
180+
broadcasts = Array.Empty<LootLockerBroadcast>();
181+
}
182+
183+
public LootLockerListBroadcastsResponse(__LootLockerInternalListBroadcastsResponse internalResponse)
184+
{
185+
if (internalResponse == null)
186+
{
187+
broadcasts = Array.Empty<LootLockerBroadcast>();
188+
return;
189+
}
190+
191+
success = internalResponse.success;
192+
statusCode = internalResponse.statusCode;
193+
requestContext = internalResponse.requestContext;
194+
EventId = internalResponse.EventId;
195+
errorData = internalResponse.errorData;
196+
text = internalResponse.text;
197+
pagination = internalResponse.pagination;
198+
199+
if (internalResponse.broadcasts == null || internalResponse.broadcasts.Length == 0)
200+
{
201+
broadcasts = Array.Empty<LootLockerBroadcast>();
202+
return;
203+
}
204+
205+
// Convert internal broadcasts to public broadcasts
206+
broadcasts = new LootLockerBroadcast[internalResponse.broadcasts.Length];
207+
for (int i = 0; i < internalResponse.broadcasts.Length; i++)
208+
{
209+
__LootLockerInternalBroadcast internalBroadcast = internalResponse.broadcasts[i];
210+
LootLockerBroadcast translatedBroadcast = new LootLockerBroadcast();
211+
translatedBroadcast.id = internalBroadcast.id;
212+
translatedBroadcast.name = internalBroadcast.name;
213+
translatedBroadcast.publication_settings = internalBroadcast.publication_settings;
214+
translatedBroadcast.language_codes = new string[internalBroadcast.languages?.Length ?? 0];
215+
translatedBroadcast.languages = new Dictionary<string, LootLockerBroadcastLanguage>();
216+
217+
for (int j = 0; j < internalBroadcast.languages.Length; j++)
218+
{
219+
var internalLang = internalBroadcast.languages[j];
220+
if (internalLang == null || string.IsNullOrEmpty(internalLang.language_code))
221+
continue;
222+
LootLockerBroadcastLanguage lang = new LootLockerBroadcastLanguage();
223+
translatedBroadcast.language_codes[j] = internalLang.language_code;
224+
lang.language_code = internalLang.language_code;
225+
lang.localizations = new Dictionary<string, string>();
226+
227+
List<string> localizationKeys = new List<string>();
228+
for (int k = 0; k < (internalLang.localizations?.Length ?? 0); k++)
229+
{
230+
switch (internalLang.localizations[k].key)
231+
{
232+
case "ll.headline":
233+
lang.headline = internalLang.localizations[k].value;
234+
break;
235+
case "ll.body":
236+
lang.body = internalLang.localizations[k].value;
237+
break;
238+
case "ll.image_url":
239+
lang.image_url = internalLang.localizations[k].value;
240+
break;
241+
case "ll.action":
242+
lang.action = internalLang.localizations[k].value;
243+
break;
244+
default:
245+
localizationKeys.Add(internalLang.localizations[k].key);
246+
lang.localizations[internalLang.localizations[k].key] = internalLang.localizations[k].value;
247+
break;
248+
}
249+
}
250+
lang.localization_keys = localizationKeys.ToArray();
251+
translatedBroadcast.languages[lang.language_code] = lang;
252+
}
253+
254+
broadcasts[i] = translatedBroadcast;
255+
}
256+
}
257+
};
258+
}

Runtime/Game/Requests/BroadcastRequest.cs.meta

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)