Prepare for CI
This commit is contained in:
@@ -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
@@ -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;"]
|
||||||
@@ -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
@@ -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
@@ -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
@@ -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: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user