Prepare for CI

This commit is contained in:
2024-05-08 23:42:23 +02:00
parent b1f6e7016a
commit b57b2db2ad
6 changed files with 313 additions and 183 deletions
+38
View File
@@ -0,0 +1,38 @@
name: release-tag
on: push
jobs:
release-image:
runs-on: ubuntu-latest
env:
DOCKER_ORG: legonzaur
DOCKER_LATEST: nightly
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Login to DockerHub
uses: docker/login-action@v2
with:
registry: git.legonzaur.fr
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Get Meta
id: meta
run: |
echo REPO_NAME=$(echo ${GITHUB_REPOSITORY} | awk -F"/" '{print $2}') >> $GITHUB_OUTPUT
echo REPO_VERSION=$(git describe --tags --always | sed 's/^v//') >> $GITHUB_OUTPUT
- name: Build and push
uses: docker/build-push-action@v4
with:
context: .
file: ./Dockerfile
push: true
tags: | # replace it with your local IP and tags
git.legonzaur.fr/${{ env.DOCKER_ORG }}/${{ steps.meta.outputs.REPO_NAME }}:${{ steps.meta.outputs.REPO_VERSION }}
git.legonzaur.fr/${{ env.DOCKER_ORG }}/${{ steps.meta.outputs.REPO_NAME }}:${{ env.DOCKER_LATEST }}
+12
View File
@@ -0,0 +1,12 @@
FROM node:lts-alpine as build-stage
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# étape de production
FROM nginx:stable-alpine as production-stage
COPY --from=build-stage /app/.output/public /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
+16 -3
View File
@@ -1,20 +1,26 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref } from "vue"; import { ref } from "vue";
import goStore, { register, setReady, oauth2_register_discord } from "@/netcode"; import goStore, { register, setReady, oauth2_register_discord, setup_websocket } from "@/netcode";
import { isStaticProperty } from "vue/compiler-sfc";
const config = useRuntimeConfig()
await setup_websocket()
const route = useRoute() const route = useRoute()
let username = ref<string>("legonzaur"); let username = ref<string>("legonzaur");
onMounted(() => { onMounted(async () => {
if (route.path != "/login") { if (route.path != "/login") {
return return
} }
const code = route.query.code const code = route.query.code
if (!code) { return } if (!code) { return }
if (Array.isArray(code)) { return } if (Array.isArray(code)) { return }
await setup_websocket()
oauth2_register_discord(code) oauth2_register_discord(code)
history.pushState( history.pushState(
@@ -24,6 +30,12 @@ onMounted(() => {
) )
}) })
async function discordLogin() {
await navigateTo(config.public.discordLoginEndpoint, {
external: true
})
}
</script> </script>
<template> <template>
<div id="game_status"> <div id="game_status">
@@ -36,6 +48,7 @@ onMounted(() => {
<template v-if="!goStore.game?.started"> <template v-if="!goStore.game?.started">
<input type="text" v-model="username" /> <input type="text" v-model="username" />
<button @click="register(username)">LOGIN</button> <button @click="register(username)">LOGIN</button>
<button @click="discordLogin()">DISCORD</button>
</template> </template>
</template> </template>
+1 -1
View File
@@ -25,7 +25,7 @@ export function create_game(input: GameNetcode, register: GameObjectRegister) {
return target.market_stack.map(e => register.cards.get(e)) return target.market_stack.map(e => register.cards.get(e))
} }
if (prop == "market") { if (prop == "market") {
console.log(target) // console.log(target)
return target.market.map(e => register.cards.get(e)) return target.market.map(e => register.cards.get(e))
} }
if (prop == "gem_stack") { if (prop == "gem_stack") {
+191 -130
View File
@@ -1,234 +1,295 @@
import { type Card, create_card, type CardNetcode } from "./Card" import { type Card, create_card, type CardNetcode } from "./Card";
import { type Effect, create_effect, type EffectNetcode, EffectType, CardEffects } from "./Effect" import {
import { type Game, create_game, type GameNetcode } from "./Game" type Effect,
import type { GameObjectNetcode } from "./GameObject" create_effect,
import { type Player, create_player, type PlayerNetcode } from "./Player" type EffectNetcode,
import { type Team, create_team, type TeamNetcode } from "./Team" EffectType,
import { type Turn, create_turn } from "./Turn" CardEffects,
} from "./Effect";
import { type Game, create_game, type GameNetcode } from "./Game";
import type { GameObjectNetcode } from "./GameObject";
import { type Player, create_player, type PlayerNetcode } from "./Player";
import { type Team, create_team, type TeamNetcode } from "./Team";
import { type Turn, create_turn } from "./Turn";
import { type Ref } from "vue" import { type Ref } from "vue";
export const socket = new WebSocket("ws://127.0.0.1:8765") let socket: WebSocket;
export class GameObjectRegister { export class GameObjectRegister {
readonly effects: Map<string, Effect>;
readonly cards: Map<string, Card>;
readonly teams: Map<string, Team>;
readonly players: Map<string, Player>;
readonly turns: Map<string, Turn>;
readonly effects: Map<string, Effect> context: "login" | "pregame" | "game" = "login";
readonly cards: Map<string, Card> private readonly objects: Map<string, GameObjectNetcode>;
readonly teams: Map<string, Team> game: Ref<Game | null>;
readonly players: Map<string, Player> self: Ref<Player | null>;
readonly turns: Map<string, Turn>
context: 'login' | 'pregame' | 'game' = "login"
private readonly objects: Map<string, GameObjectNetcode>
game: Ref<Game | null>
self: Ref<Player | null>
constructor() { constructor() {
this.effects = reactive(new Map()) this.effects = reactive(new Map());
this.cards = reactive(new Map()) this.cards = reactive(new Map());
this.teams = reactive(new Map()) this.teams = reactive(new Map());
this.players = reactive(new Map()) this.players = reactive(new Map());
this.turns = reactive(new Map()) this.turns = reactive(new Map());
this.objects = reactive(new Map()) this.objects = reactive(new Map());
this.game = ref(null) this.game = ref(null);
this.self = ref(null) this.self = ref(null);
} }
update_object(obj: GameObjectNetcode) { update_object(obj: GameObjectNetcode) {
Object.assign(this.objects.get(obj.uuid) as GameNetcode, obj) Object.assign(this.objects.get(obj.uuid) as GameNetcode, obj);
} }
createObject = { createObject = {
"effect": (data: EffectNetcode) => { effect: (data: EffectNetcode) => {
const effect = create_effect(data, this) const effect = create_effect(data, this);
this.effects.set(data.uuid, effect) this.effects.set(data.uuid, effect);
this.objects.set(data.uuid, data) this.objects.set(data.uuid, data);
}, },
"card": (data: CardNetcode) => { card: (data: CardNetcode) => {
const card = create_card(data, this) const card = create_card(data, this);
this.cards.set(data.uuid, card) this.cards.set(data.uuid, card);
this.objects.set(data.uuid, card) this.objects.set(data.uuid, card);
}, },
"player": (data: PlayerNetcode) => { player: (data: PlayerNetcode) => {
const player = create_player(data, this) const player = create_player(data, this);
this.players.set(data.uuid, player) this.players.set(data.uuid, player);
this.objects.set(data.uuid, player) this.objects.set(data.uuid, player);
}, },
"team": (data: TeamNetcode) => { team: (data: TeamNetcode) => {
const team = create_team(data, this) const team = create_team(data, this);
this.teams.set(data.uuid, team) this.teams.set(data.uuid, team);
this.objects.set(data.uuid, team) this.objects.set(data.uuid, team);
}, },
"game": (data: GameNetcode) => { game: (data: GameNetcode) => {
this.game.value = create_game(data, this) this.game.value = create_game(data, this);
this.objects.set(data.uuid, this.game.value) this.objects.set(data.uuid, this.game.value);
}, },
"turn": (data: any) => { turn: (data: any) => {
const turn = create_turn(data, this) const turn = create_turn(data, this);
this.turns.set(data.uuid, turn) this.turns.set(data.uuid, turn);
this.objects.set(data.uuid, turn) this.objects.set(data.uuid, turn);
} },
} as { [id: string]: (data: any) => any } } as { [id: string]: (data: any) => any };
set_self = (uuid: string) => { set_self = (uuid: string) => {
this.self.value = this.players.get(uuid) ?? null this.self.value = this.players.get(uuid) ?? null;
} };
} }
const goStore = reactive(new GameObjectRegister()) const goStore = reactive(new GameObjectRegister());
export const setup_websocket = () =>
new Promise<void>((resolve, reject) => {
if (socket) {
return resolve();
}
const config = useRuntimeConfig();
socket = new WebSocket(config.public.websocketEndpoint);
socket.onopen = function (e) {
if (socket.readyState == 1) {
resolve();
}
socket.onopen = function (e) {
console.log("[open] Connection established"); console.log("[open] Connection established");
}; };
socket.onclose = function (event) { socket.onclose = function (event) {
if (event.wasClean) { if (event.wasClean) {
console.warn(`[close] Connection closed cleanly, code=${event.code} reason=${event.reason}`); console.warn(
`[close] Connection closed cleanly, code=${event.code} reason=${event.reason}`
);
} else { } else {
// e.g. server process killed or network down // e.g. server process killed or network down
// event.code is usually 1006 in this case // event.code is usually 1006 in this case
console.error('[close] Connection died'); console.error("[close] Connection died");
} }
}; };
socket.onerror = function (error) { socket.onerror = function (error) {
console.error(error); console.error(error);
}; };
socket.onmessage = function (event) {
const data = JSON.parse(event.data)
socket.onmessage = function (event) {
const data = JSON.parse(event.data);
if (data.type == "create" && data.data_type == "object") { if (data.type == "create" && data.data_type == "object") {
if (!(data.data.object_type in goStore.createObject)) { if (!(data.data.object_type in goStore.createObject)) {
throw new Error(`Object ${data.data.object_type} couldn't be created`) throw new Error(
`Object ${data.data.object_type} couldn't be created`
);
} }
goStore.createObject[data.data.object_type](data.data) goStore.createObject[data.data.object_type](data.data);
} else if (data.type == "update" && data.data_type == "object") { } else if (data.type == "update" && data.data_type == "object") {
goStore.update_object(data.data) goStore.update_object(data.data);
} else if (data.type === "context") { } else if (data.type === "context") {
goStore.context = data.data goStore.context = data.data;
console.log(data.data) // console.log(data.data);
} else if (data.type === "set" && data.data_type == "self") { } else if (data.type === "set" && data.data_type == "self") {
goStore.set_self(data.data) goStore.set_self(data.data);
} else { } else {
console.log(data.type, data.data_type, data.data); // console.log(data.type, data.data_type, data.data);
} }
}; };
});
export async function oauth2_register_discord(code: string){ export async function oauth2_register_discord(code: string) {
socket.send(JSON.stringify({ await setup_websocket();
type:"discord_login", socket.send(
data_type:"code", JSON.stringify({
data:code type: "discord_login",
})) data_type: "code",
data: code,
})
);
} }
export async function register(username: string) { export async function register(username: string) {
socket.send(JSON.stringify({ await setup_websocket();
socket.send(
JSON.stringify({
type: "register", type: "register",
data_type: "username", data_type: "username",
data: username data: username,
})) })
);
} }
export async function login(username: string) { export async function login(username: string) {
socket.send(JSON.stringify({ await setup_websocket();
socket.send(
JSON.stringify({
type: "login", type: "login",
data_type: "username", data_type: "username",
data: username data: username,
})) })
);
} }
export async function setReady(value: boolean) { export async function setReady(value: boolean) {
socket.send(JSON.stringify({ await setup_websocket();
socket.send(
JSON.stringify({
type: "ready", type: "ready",
data_type: "ready_state", data_type: "ready_state",
data: value data: value,
})) })
);
} }
export async function buy(card: Card) { export async function buy(card: Card) {
socket.send(JSON.stringify({ await setup_websocket();
socket.send(
JSON.stringify({
type: "action", type: "action",
data_type: "buy", data_type: "buy",
data: card.uuid data: card.uuid,
})) })
);
} }
export async function endTurn() { export async function endTurn() {
socket.send(JSON.stringify({ await setup_websocket();
socket.send(
JSON.stringify({
type: "action", type: "action",
data_type: "end_turn", data_type: "end_turn",
data: true data: true,
})) })
);
} }
export function playAllCards(cards: Card[]) { export function playAllCards(cards: Card[]) {
cards.forEach((c: any) => { cards.forEach((c: any) => {
playCard(c) playCard(c);
}); });
} }
export function playCard(card: Card) { export async function playCard(card: Card) {
console.log(card.uuid) // console.log(card.uuid);
socket.send(JSON.stringify({ await setup_websocket();
socket.send(
JSON.stringify({
type: "action", type: "action",
data_type: "play_card", data_type: "play_card",
data: card.uuid data: card.uuid,
})) })
);
} }
export function lockCard(card: Card) { export async function lockCard(card: Card) {
socket.send(JSON.stringify({ await setup_websocket();
socket.send(
JSON.stringify({
type: "action", type: "action",
data_type: "lock_card", data_type: "lock_card",
data: card.uuid data: card.uuid,
})) })
);
} }
export function useEffect(effect: Effect, target?: Effect | Card | Player | Team) { export async function useEffect(
socket.send(JSON.stringify({ effect: Effect,
target?: Effect | Card | Player | Team
) {
await setup_websocket();
socket.send(
JSON.stringify({
type: "action", type: "action",
data_type: "use_effect", data_type: "use_effect",
data: { effect_id: effect.uuid, target: target?.uuid } data: { effect_id: effect.uuid, target: target?.uuid },
})) })
);
} }
export function discard(card: Card) { export async function discard(card: Card) {
socket.send(JSON.stringify({ await setup_websocket();
socket.send(
JSON.stringify({
type: "action", type: "action",
data_type: "discard", data_type: "discard",
data: card.uuid data: card.uuid,
})) })
);
} }
h h;
export function heal() { export async function heal() {
socket.send(JSON.stringify({ await setup_websocket();
socket.send(
JSON.stringify({
type: "action", type: "action",
data_type: "heal", data_type: "heal",
data: 1 data: 1,
})) })
);
} }
export function damage_team(target: Team) { export async function damage_team(target: Team) {
socket.send(JSON.stringify({ await setup_websocket();
socket.send(
JSON.stringify({
type: "action", type: "action",
data_type: "damage_team", data_type: "damage_team",
data: target.uuid data: target.uuid,
})) })
);
} }
export function damage_champion(target: Card) { export async function damage_champion(target: Card) {
socket.send(JSON.stringify({ await setup_websocket();
socket.send(
JSON.stringify({
type: "action", type: "action",
data_type: "damage_champion", data_type: "damage_champion",
data: target.uuid data: target.uuid,
})) })
);
} }
export default goStore export default goStore;
+7 -1
View File
@@ -1,5 +1,11 @@
// https://nuxt.com/docs/api/configuration/nuxt-config // https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({ export default defineNuxtConfig({
devtools: { enabled: true }, devtools: { enabled: true },
ssr: false ssr: false,
runtimeConfig: {
public: {
websocketEndpoint: 'ws://127.0.0.1:8765', // can be overridden by NUXT_PUBLIC_API_BASE environment variable
discordLoginEndpoint: ''
}
},
}) })