GS2-News

Notification delivery feature

A mechanism for delivering in-game announcements in HTML format. The HTML content to be delivered must be generated by hugo (https://gohugo.io/).

When you upload article data to GS2-News, GS2 builds it with hugo and hosts it as static web content. Game clients can view the announcements by accessing the temporary URLs delivered by GS2.

graph LR
  Author["Operator"] -- "ZIP upload" --> GS2["GS2-News"]
  GS2 -- "hugo build (pre-generates all<br/>public/non-public patterns)" --> CDN["CDN (HTML / ZIP)"]
  Player["Player"] -- "GetContentsUrl" --> GS2
  GS2 -- "URL + Cookie<br/>(valid for 1 hour)" --> Player
  Player -- "WebView or ZIP DL" --> CDN

hugo

hugo is a generator for producing static web pages.

It generates HTML files by building templates that determine the page layout and design, together with article data written in Markdown format. For details on how to use hugo, refer to the official hugo site or various tutorial sites.

GS2 provides a minimal hugo template and sample article data on GitHub.

https://github.com/gs2io/gs2-news-sample

Articles Linked to Events

GS2-News can manage article data that is linked to events managed by GS2-Schedule.

You can enable the linkage by writing the following in the front matter of the article data Markdown file.

x_gs2_scheduleEventId: ${GS2-Schedule event GRN}

In addition, the following placeholders can be used in the GS2-Schedule event ID.

Placeholder Substituted Value
{region} Region name
{ownerId} GS2 owner ID

An example is shown below.

x_gs2_scheduleEventId: grn:gs2:{region}:{ownerId}:schedule:schedule-0001:event:event-0001

You can automatically control articles that are displayed only while an event is ongoing, or articles that are hidden only during a specific event period, without operating an admin tool.

Article Data Size Limit

The total article data uploaded to GS2-News must be within 100 MB.

Also, the --buildDrafts option is not included when building article data. Content with draft: true in its front matter will not be delivered.

Building Article Data

Article data delivered by GS2-News is updated by uploading a zip-compressed hugo template and article files. Afterwards, GS2-News builds and delivers the article data.

If x_gs2_scheduleEventId is described in the article data, each article is built in advance for both the public and non-public state, and the results are placed on the web server.

Then, when a player tries to access the article data, GS2-News responds with the most appropriate content URL based on the current event status.

sequenceDiagram
  participant U as Operator
  participant N as GS2-News
  participant CDN as CDN
  U->>N: PrepareUpdateCurrentNewsMaster
  N-->>U: Upload URL
  U->>N: HTTP PUT (zip)
  U->>N: UpdateCurrentNewsMaster
  N->>N: Build all patterns<br/>with hugo
  N->>CDN: Place static content

You can check the progress with the Progress model (generated / patternCount) and poll whether a long-running build has completed.

Access Control for Article Data

We explained that article data is pre-built in all patterns before being delivered. Malicious players must not be able to guess URLs and access content that has not yet been published.

To avoid this problem, GS2-News implements access restrictions using cookies. When you obtain the URL of the currently active content, you also obtain the cookie information needed to access that URL. By setting that cookie in the browser and accessing the content URL, you can download the content.

The cookie has an expiration; one hour after obtaining it, the cookie can no longer be used to access content. For players who play for a long time, please re-acquire the cookie.

Downloading Web Content as a Zip

In addition to accessing the HTML hosted by GS2-News via WebView, you can also download the entire HTML produced by GS2-News as a zip.

Using this method, you can extract the downloaded zip content to local storage and view it in a browser, providing a smoother browsing experience and avoiding repeatedly downloading the same content.

To determine whether the zip file should be re-downloaded, GS2-News exposes hash values for the template file and for the published content set determined by GS2-Schedule. By using these values, you can determine whether to re-download the zip file.

Hash Description
TemplateHash Hash of the uploaded template ZIP. Changes when the template itself is updated.
ContentHash Hash of the set of published content determined by the current event status. Changes when events start or end.

Script Triggers

GS2-News does not provide script triggers.

Master Data Management

By registering master data, you can configure the data and behaviors available in the microservice.

The types of master data are as follows.

  • Template: Hugo template for displaying news
  • Article: News articles in Markdown format

In addition to registering master data from the management console, you can also reflect data from GitHub or build a workflow that registers it from CI using GS2-Deploy.

Transaction Actions

GS2-News does not provide transaction actions.

Implementation Examples

Retrieving the Content URL

The return value of GetContentsUrl includes a list of cookies, BrowserUrl (for viewing in WebView), and ZipUrl (for downloading as ZIP). After registering the obtained cookies in the WebView or HTTP client, access each URL.

    var domain = gs2.News.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).News(
    );
    var result = await domain.GetContentsUrlAsync(
    );

    List<EzSetCookieRequestEntry> cookies = new List<EzSetCookieRequestEntry>();
    var items = result.ToList();
    foreach (var item in items)
    {
        var entry = await item.ModelAsync();
        cookies.Add(entry);
    }
    var browserUrl = domain.BrowserUrl;
    var zipUrl = domain.ZipUrl;
    const auto Domain = Gs2->News->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        AccessToken
    )->News(
    );
    const auto Future = Domain->GetContentsUrl(
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError()) return false;
    TArray<EzSetCookieRequestEntryPtr> Cookies;
    const auto It = Future->GetTask().Result();
    foreach (auto Item in It)
    {
        const auto Future2 = Item.Model();
        Future2->StartSynchronousTask();
        if (Future2->GetTask().IsError()) return false;
        Cookies.Add(Future->GetTask().Result());
    }
    const auto BrowserUrl = Domain->BrowserUrl;
    const auto ZipUrl = Domain->ZipUrl;

Example of Displaying in a WebView (Unity)

Using unity-webview, set the obtained cookies on the WebView and then open BrowserUrl to display the news.

    foreach (var cookie in cookies) {
        webView.SetCookie(browserUrl, cookie.Key, cookie.Value);
    }
    webView.LoadURL(browserUrl);
    webView.SetVisibility(true);

Retrieving a List of Article Data

Each article holds Section, Title, Content, FrontMatter, etc. You can also use a configuration where you display the title list with your own UI and only display the selected article in a WebView.

    var domain = gs2.News.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    var items = await domain.NewsesAsync(
    ).ToListAsync();
    var templateHash = domain.TemplateHash;
    var contentHash = domain.ContentHash;
    const auto Domain = Gs2->News->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        AccessToken
    );
    const auto It = Domain->Newses(
    );
    TArray<Gs2::UE5::News::Model::FEzNewsPtr> Result;
    for (auto Item : *It)
    {
        if (Item.IsError())
        {
            return false;
        }
        Result.Add(Item.Current());
    }

Deciding Whether to Re-download the Cache

If you adopt the ZIP download approach, you can save TemplateHash and ContentHash locally and compare them against the values re-fetched on startup, to avoid unnecessary re-downloads of the ZIP.

    if (savedTemplateHash != domain.TemplateHash ||
        savedContentHash != domain.ContentHash) {
        // Re-download
    }

Detailed Reference