PageSourceSearch

https://uflgame.com/wp-content/themes/theme/assets/js/gsid.js?ver=1789650020

js uflgame.com collected 2026-09-24 10:47:10 UTC 6,340 bytes, 196 lines download raw bytes

1;(function () {
2  // Gamesight gsid -> launcher download link.
3  // Injects the per-visitor Gamesight Session ID into download URLs as
4  // ?distr=<gsid> and mirrors it into a first-party cookie.
5  //
6  // Not gated on cookie consent: gsid generation is handled by analytics.js;
7  // here we just wait for gsid to become available and rewrite the buttons.
8  // Without a gsid the buttons keep their original href.
9  //
10  // Both cookies are also written back after a consent submit — see restoreCookies().
11  //
12  // Target buttons: any link explicitly marked with data-gs-distr, plus any link
13  // pointing at the Gaijin launcher — so every Download button on every page is
14  // covered without per-button admin toggles or hardcoded distr values.
15
16  var BUTTON_SELECTOR = 'a[data-gs-distr], a[href*="gdn.gaijin.net/launcher"]'
17  var DISTR_PARAM = 'distr'
18  var COOKIE_NAME = 'gsid'
19  var COOKIE_MAX_AGE = 60 * 60 * 24 * 30 // 30 days
20  var SDK_COOKIE_NAME = '_gsid'
21  var SDK_COOKIE_MAX_AGE = 60 * 60 * 24 * 365 // the SDK's own lifetime
22  var POLL_INTERVAL = 200
23  var POLL_TIMEOUT = 8000
24  var RESTORE_INTERVAL = 100
25  var RESTORE_TIMEOUT = 2000
26
27  var applied = false
28  var polling = false
29  var restoring = false
30  var known = '' // last id seen, kept for restoreCookies()
31
32  function buttons() {
33    return document.querySelectorAll(BUTTON_SELECTOR)
34  }
35
36  function forEach(list, fn) {
37    Array.prototype.forEach.call(list, fn)
38  }
39
40  // Gamesight Web SDK: gsght('get', 'gsid') returns the Session ID once the SDK
41  // has loaded and been initialized (see docs.gamesight.io self-distribution).
42  function getGsid() {
43    if (!window.gsght) return ''
44    try {
45      var id = window.gsght('get', 'gsid')
46      return typeof id === 'string' ? id : ''
47    } catch (e) {
48      return ''
49    }
50  }
51
52  // Parsed with string operations on purpose: Autoptimize's JS minifier drops the
53  // line break after a regex literal that has no flags.
54  function cookieValue(name, raw) {
55    var parts = document.cookie ? document.cookie.split(';') : []
56
57    for (var i = 0; i < parts.length; i++) {
58      var pair = parts[i].split('=')
59      if (pair.shift().trim() !== name) continue
60
61      var value = pair.join('=')
62      if (raw) return value
63
64      try {
65        return decodeURIComponent(value)
66      } catch (e) {
67        return value
68      }
69    }
70
71    return ''
72  }
73
74  function setDistr(href, gsid) {
75    try {
76      var url = new URL(href, window.location.href)
77      url.searchParams.set(DISTR_PARAM, gsid)
78      return url.toString()
79    } catch (e) {
80      return href // keep original href on malformed URL
81    }
82  }
83
84  function writeCookie(gsid) {
85    document.cookie = COOKIE_NAME + '=' + encodeURIComponent(gsid) +
86      '; path=/; max-age=' + COOKIE_MAX_AGE + '; SameSite=Lax'
87  }
88
89  // Mirrors where the SDK puts _gsid: it drops the first label of the host, and
90  // falls back to the full host when that leaves a bare TLD the browser rejects.
91  // Landing anywhere else would leave a second _gsid the SDK may read instead.
92  function sdkCookieDomain() {
93    var labels = window.location.hostname.split('.')
94    if (labels.length === 1) return '' // no domain attribute on a bare host
95
96    labels.shift()
97    if (labels.length === 1) return '; domain=.' + window.location.hostname
98
99    return '; domain=.' + labels.join('.')
100  }
101
102  // Written the way the SDK writes it — same name, domain and lifetime, and the
103  // bare uuid it stores, unencoded — so the SDK picks the id back up on the next
104  // page view instead of minting a new one.
105  function writeSdkCookie(gsid) {
106    document.cookie = SDK_COOKIE_NAME + '=' + gsid +
107      '; path=/; max-age=' + SDK_COOKIE_MAX_AGE + sdkCookieDomain()
108  }
109
110  function apply(gsid) {
111    if (applied) return
112    known = gsid
113    writeCookie(gsid)
114    writeSdkCookie(gsid)
115    forEach(buttons(), function (btn) {
116      var href = btn.getAttribute('href')
117      if (!href) return
118      btn.setAttribute('href', setDistr(href, gsid))
119    })
120    applied = true
121  }
122
123  function waitForGsid() {
124    if (polling || applied) return
125    var gsid = getGsid()
126    if (gsid) { apply(gsid); return }
127
128    polling = true
129    var elapsed = 0
130    var timer = setInterval(function () {
131      elapsed += POLL_INTERVAL
132      var id = getGsid()
133      if (id) {
134        clearInterval(timer)
135        polling = false
136        apply(id)
137      } else if (elapsed >= POLL_TIMEOUT) {
138        clearInterval(timer)
139        polling = false // give up; fallback href stays
140      }
141    }, POLL_INTERVAL)
142  }
143
144  // Mirrors analytics.js: with the rollback flag off, consent governs the id again
145  // and putting the cookies back would defeat it.
146  function preConsentEnabled() {
147    return !(window.UFL_GSID && window.UFL_GSID.preConsent === false)
148  }
149
150  function writeBoth() {
151    writeCookie(known)
152    writeSdkCookie(known)
153  }
154
155  // Cookiebot wipes its Unclassified category on every consent submit, accept and
156  // decline alike, and both ids are listed there. The value is still in memory, so
157  // it is written back. The wipe is not ordered against the events Cookiebot
158  // dispatches, so the window is watched rather than guessed at — a wipe arriving
159  // late would otherwise drop the id silently.
160  // Drop this once the ids are classified in the Cookiebot panel.
161  function restoreCookies() {
162    if (!known || restoring) return
163
164    writeBoth()
165
166    restoring = true
167    var elapsed = 0
168    var timer = setInterval(function () {
169      elapsed += RESTORE_INTERVAL
170
171      if (cookieValue(COOKIE_NAME) !== known ||
172          cookieValue(SDK_COOKIE_NAME, true) !== known) writeBoth()
173
174      if (elapsed >= RESTORE_TIMEOUT) {
175        clearInterval(timer)
176        restoring = false
177      }
178    }, RESTORE_INTERVAL)
179  }
180
181  function init() {
182    known = known || cookieValue(COOKIE_NAME) || cookieValue(SDK_COOKIE_NAME, true)
183
184    if (preConsentEnabled()) {
185      window.addEventListener('CookiebotOnConsentReady', restoreCookies)
186      window.addEventListener('CookiebotOnAccept', restoreCookies)
187      window.addEventListener('CookiebotOnDecline', restoreCookies)
188    }
189
190    // Runs on every page, not only where there is a button to rewrite: a visitor
191    // who consents on a page without one has to carry the id onwards too.
192    waitForGsid()
193  }
194
195  document.addEventListener('DOMContentLoaded', init)
196})()

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.