Skip to content
This repository has been archived by the owner on Nov 13, 2023. It is now read-only.

Commit

Permalink
Merge branch feature/cookies into main (#88)
Browse files Browse the repository at this point in the history
* Implement CookieManager

- Implement Cookie class
- Implement CookieManager class
- Let CookieManager be available through Services

* Fully implement Cookie framework

- Fully implement Cookie class
- Fully implement CookieManager
- Let engine load cookies on start automatically
  • Loading branch information
Kitt3120 committed Jun 15, 2023
1 parent 6ce9de0 commit a07554f
Show file tree
Hide file tree
Showing 4 changed files with 198 additions and 4 deletions.
69 changes: 69 additions & 0 deletions src/ts/engine/cookies/cookie.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
class Cookie {
private _value: string;
private _expires: Date | null;
private _sameSite: "Strict" | "Lax" | "None" | null;
private _secure: boolean | null;
private _updated: boolean;

public get value(): string {
return this._value;
}

public get expires(): Date | null {
return this._expires;
}

public get sameSite(): "Strict" | "Lax" | "None" | null {
return this._sameSite;
}

public get secure(): boolean | null {
return this._secure;
}

public get updated(): boolean {
return this._updated;
}

public set updated(value: boolean) {
this._updated = value;
}

public get fullySpecified(): boolean {
return (
this._value.length > 0 &&
this._expires !== null &&
this._sameSite !== null &&
this._secure !== null
);
}

public constructor(
value: string,
expires: Date | null,
sameSite: "Strict" | "Lax" | "None" | null,
secure: boolean | null,
updated: boolean = true
) {
this._value = value;
this._expires = expires;
this._sameSite = sameSite;
this._secure = secure;
this._updated = updated;
}

public update(
value: string,
expires: Date,
sameSite: "Strict" | "Lax" | "None",
secure: boolean
): void {
this._value = value;
this._expires = expires;
this._sameSite = sameSite;
this._secure = secure;
this._updated = true;
}
}

export default Cookie;
120 changes: 120 additions & 0 deletions src/ts/engine/cookies/cookiemanager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import Cookie from "./cookie.js";

class CookieManager {
private readonly _firstDate1970UTC: string;

private _cookies: Map<string, Cookie>;

public get cookies(): Map<string, Cookie> {
return this._cookies;
}

public constructor() {
this._firstDate1970UTC = new Date(0).toUTCString();
this._cookies = new Map<string, Cookie>();
}

public has(name: string): boolean {
return this._cookies.has(name);
}

public get(name: string): Cookie {
if (!this.has(name)) {
throw new Error(`Cookie with name '${name}' does not exist.`);
}

return this._cookies.get(name) as Cookie;
}

public set(name: string, cookie: Cookie): void {
this._cookies.set(name, cookie);
}

public getOrSet(name: string, cookie: Cookie): Cookie {
if (this.has(name)) {
return this.get(name);
}

this.set(name, cookie);
return cookie;
}

public delete(name: string): void {
this._cookies.delete(name);
}

public clear(): void {
this._cookies.clear();
}

public load(): void {
let newCookies: Map<string, Cookie> = new Map<string, Cookie>();

let cookieString = document.cookie.trim();
if (cookieString) {
let split = cookieString.split(";");
for (let part of split) {
let [name, value] = part.split("=");

if (!name) {
throw new Error("Failed to load cookie: Name is empty.");
}

if (!value) {
throw new Error(`Failed to load cookie ${name}: Value is empty.`);
}
let cookie: Cookie = new Cookie(
decodeURI(value),
null,
null,
null,
false
);
newCookies.set(name.trim(), cookie);
}
}

this._cookies = newCookies;
}

public cleanBrowserCookies(): void {
let cookieString = document.cookie.trim();

if (cookieString) {
let split = document.cookie.split(";");
for (let part of split) {
let name = part.split("=")[0];
if (!this.has(name)) {
document.cookie = `${name.trim()};Expires=${
this._firstDate1970UTC
};SameSite=Lax`;
}
}
}
}

public save(): void {
this.cleanBrowserCookies();

for (let [name, cookie] of this._cookies) {
if (cookie.updated) {
if (!cookie.fullySpecified) {
console.warn(
`Cookie ${name} was updated but not fully specified. Can't save updated value to disk!`
);
continue;
}

let expires: string = cookie.expires!.toUTCString();
let sameSite: string = cookie.sameSite!;
let secure: string = cookie.secure! ? "true" : "false";

document.cookie = `${name}=${encodeURI(
cookie.value
)};Expires=${expires};SameSite=${sameSite};Secure=${secure}`;
}
}
}
}

export default CookieManager;
6 changes: 6 additions & 0 deletions src/ts/engine/game.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import AssetLoader from "./assets/assetloader.js";
import AssetManager from "./assets/assetmanager.js";
import CookieManager from "./cookies/cookiemanager.js";
import Services from "./dependencyinjection/services.js";
import EngineSetup from "./enginesetup.js";
import EntityManager from "./entitiy/entitymanager.js";
Expand All @@ -12,6 +13,7 @@ import SettingsManager from "./settings/settingsmanager.js";
class Game {
private _assetLoader: AssetLoader;
private _assetManager: AssetManager;
private _cookieManager: CookieManager;
private _settingsManager: SettingsManager;
private _inputHandler: InputHandler;
private _sceneManager: SceneManager;
Expand Down Expand Up @@ -44,6 +46,7 @@ class Game {
constructor(htmlCanvasElement: HTMLCanvasElement, engineSetup: EngineSetup) {
this._assetLoader = new AssetLoader();
this._assetManager = new AssetManager();
this._cookieManager = new CookieManager();
this._settingsManager = new SettingsManager();
this._inputHandler = new InputHandler(htmlCanvasElement);
this._sceneManager = new SceneManager(this._inputHandler);
Expand All @@ -68,6 +71,7 @@ class Game {

Services.register(this._assetLoader);
Services.register(this._assetManager);
Services.register(this._cookieManager);
Services.register(this._settingsManager);
Services.register(this._inputHandler);
Services.register(this._sceneManager);
Expand All @@ -76,6 +80,8 @@ class Game {
Services.register(this._compositor);
Services.register(this);

this._cookieManager.load();

engineSetup.loadAssets(
this._assetLoader,
this._assetManager,
Expand Down
7 changes: 3 additions & 4 deletions src/ts/game/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import AssetManager from "../engine/assets/assetmanager.js";
import Slice from "../engine/assets/texture/slice.js";
import SliceTexture from "../engine/assets/texture/slicetexture.js";
import SpriteSheet from "../engine/assets/texture/spritesheet.js";
import Cookie from "../engine/cookies/cookie.js";
import CookieManager from "../engine/cookies/cookiemanager.js";
import Services from "../engine/dependencyinjection/services.js";
import Game from "../engine/game.js";
import InputHandler from "../engine/input/inputhandler.js";
Expand Down Expand Up @@ -36,10 +38,7 @@ function start(): void {
inputHandler.addWhiteListedKeys(["F5", "F11", "F12", "Alt"]);

game.startGame();

let sceneManager: SceneManager =
Services.resolve<SceneManager>("SceneManager");
sceneManager.switch("mainmenu");
Services.resolve<SceneManager>("SceneManager").switch("mainmenu");
}

window.addEventListener("DOMContentLoaded", start);

0 comments on commit a07554f

Please sign in to comment.