feat: huge change
24
nginx.conf
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
server {
|
||||
listen 80;
|
||||
server_name localhost;
|
||||
|
||||
location / {
|
||||
proxy_pass http://ms.r1delta.net;
|
||||
proxy_set_header Host ms.r1delta.net;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# 设置超时时间
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 60s;
|
||||
proxy_read_timeout 60s;
|
||||
|
||||
# 允许较大的请求体
|
||||
client_max_body_size 50M;
|
||||
|
||||
# 启用压缩
|
||||
gzip on;
|
||||
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
|
||||
}
|
||||
}
|
||||
12
package.json
|
|
@ -8,17 +8,19 @@
|
|||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"vue": "^3.3.4",
|
||||
"vue-i18n": "^9.2.2",
|
||||
"vue-router": "^4.2.4",
|
||||
"@heroicons/vue": "^2.0.18",
|
||||
"axios": "^1.4.0",
|
||||
"@heroicons/vue": "^2.0.18"
|
||||
"vue": "^3.3.4",
|
||||
"vue-i18n": "12.0.0-alpha.2",
|
||||
"vue-router": "^4.2.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^22.15.17",
|
||||
"@vitejs/plugin-vue": "^4.2.3",
|
||||
"autoprefixer": "^10.4.14",
|
||||
"postcss": "^8.4.27",
|
||||
"tailwindcss": "^3.3.3",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^4.4.9"
|
||||
}
|
||||
}
|
||||
}
|
||||
116
pnpm-lock.yaml
generated
|
|
@ -10,23 +10,26 @@ importers:
|
|||
dependencies:
|
||||
'@heroicons/vue':
|
||||
specifier: ^2.0.18
|
||||
version: 2.2.0(vue@3.5.13)
|
||||
version: 2.2.0(vue@3.5.13(typescript@5.8.3))
|
||||
axios:
|
||||
specifier: ^1.4.0
|
||||
version: 1.9.0
|
||||
vue:
|
||||
specifier: ^3.3.4
|
||||
version: 3.5.13
|
||||
version: 3.5.13(typescript@5.8.3)
|
||||
vue-i18n:
|
||||
specifier: ^9.2.2
|
||||
version: 9.14.4(vue@3.5.13)
|
||||
specifier: 12.0.0-alpha.2
|
||||
version: 12.0.0-alpha.2(vue@3.5.13(typescript@5.8.3))
|
||||
vue-router:
|
||||
specifier: ^4.2.4
|
||||
version: 4.5.1(vue@3.5.13)
|
||||
version: 4.5.1(vue@3.5.13(typescript@5.8.3))
|
||||
devDependencies:
|
||||
'@types/node':
|
||||
specifier: ^22.15.17
|
||||
version: 22.15.17
|
||||
'@vitejs/plugin-vue':
|
||||
specifier: ^4.2.3
|
||||
version: 4.6.2(vite@4.5.14)(vue@3.5.13)
|
||||
version: 4.6.2(vite@4.5.14(@types/node@22.15.17))(vue@3.5.13(typescript@5.8.3))
|
||||
autoprefixer:
|
||||
specifier: ^10.4.14
|
||||
version: 10.4.21(postcss@8.5.3)
|
||||
|
|
@ -36,9 +39,12 @@ importers:
|
|||
tailwindcss:
|
||||
specifier: ^3.3.3
|
||||
version: 3.4.17
|
||||
typescript:
|
||||
specifier: ^5.8.3
|
||||
version: 5.8.3
|
||||
vite:
|
||||
specifier: ^4.4.9
|
||||
version: 4.5.14
|
||||
version: 4.5.14(@types/node@22.15.17)
|
||||
|
||||
packages:
|
||||
|
||||
|
|
@ -200,18 +206,24 @@ packages:
|
|||
peerDependencies:
|
||||
vue: '>= 3'
|
||||
|
||||
'@intlify/core-base@9.14.4':
|
||||
resolution: {integrity: sha512-vtZCt7NqWhKEtHa3SD/322DlgP5uR9MqWxnE0y8Q0tjDs9H5Lxhss+b5wv8rmuXRoHKLESNgw9d+EN9ybBbj9g==}
|
||||
'@intlify/core-base@12.0.0-alpha.2':
|
||||
resolution: {integrity: sha512-sPWvQ1Z4Wyw9Kp8xqjAk2sMOeZ4pO7p/NL3Eol8l9a7iPyMTuHyJ2DZVbOBG6zDnCupvLAqnRMAT1LAgvx0QRQ==}
|
||||
engines: {node: '>= 16'}
|
||||
|
||||
'@intlify/message-compiler@9.14.4':
|
||||
resolution: {integrity: sha512-vcyCLiVRN628U38c3PbahrhbbXrckrM9zpy0KZVlDk2Z0OnGwv8uQNNXP3twwGtfLsCf4gu3ci6FMIZnPaqZsw==}
|
||||
'@intlify/message-compiler@12.0.0-alpha.2':
|
||||
resolution: {integrity: sha512-PD9C+oQbb7BF52hec0+vLnScaFkvnfX+R7zSbODYuRo/E2niAtGmHd0wPvEMsDhf9Z9b8f/qyDsVeZnD/ya9Ug==}
|
||||
engines: {node: '>= 16'}
|
||||
|
||||
'@intlify/shared@9.14.4':
|
||||
resolution: {integrity: sha512-P9zv6i1WvMc9qDBWvIgKkymjY2ptIiQ065PjDv7z7fDqH3J/HBRBN5IoiR46r/ujRcU7hCuSIZWvCAFCyuOYZA==}
|
||||
'@intlify/shared@12.0.0-alpha.2':
|
||||
resolution: {integrity: sha512-P2DULVX9nz3y8zKNqLw9Es1aAgQ1JGC+kgpx5q7yLmrnAKkPR5MybQWoEhxanefNJgUY5ehsgo+GKif59SrncA==}
|
||||
engines: {node: '>= 16'}
|
||||
|
||||
'@intlify/vue-i18n-core@12.0.0-alpha.2':
|
||||
resolution: {integrity: sha512-y1NPEcPbD8xqWGiaEREkA9WxxWbxmd8IurN176w39MenZKEf5P20rYyk0w4r718+w/9jjm0m5zR1ed6uMaZT2Q==}
|
||||
engines: {node: '>= 16'}
|
||||
peerDependencies:
|
||||
vue: ^3.0.0
|
||||
|
||||
'@isaacs/cliui@8.0.2':
|
||||
resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
|
||||
engines: {node: '>=12'}
|
||||
|
|
@ -250,6 +262,9 @@ packages:
|
|||
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
'@types/node@22.15.17':
|
||||
resolution: {integrity: sha512-wIX2aSZL5FE+MR0JlvF87BNVrtFWf6AE6rxSE9X7OwnVvoyCQjpzSRJ+M87se/4QCkCiebQAqrJ0y6fwIyi7nw==}
|
||||
|
||||
'@vitejs/plugin-vue@4.6.2':
|
||||
resolution: {integrity: sha512-kqf7SGFoG+80aZG6Pf+gsZIVvGSCKE98JbiWqcCV9cThtg91Jav0yvYFC9Zb+jKetNGF6ZKeoaxgZfND21fWKw==}
|
||||
engines: {node: ^14.18.0 || >=16.0.0}
|
||||
|
|
@ -784,6 +799,14 @@ packages:
|
|||
ts-interface-checker@0.1.13:
|
||||
resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
|
||||
|
||||
typescript@5.8.3:
|
||||
resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==}
|
||||
engines: {node: '>=14.17'}
|
||||
hasBin: true
|
||||
|
||||
undici-types@6.21.0:
|
||||
resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
|
||||
|
||||
update-browserslist-db@1.1.3:
|
||||
resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==}
|
||||
hasBin: true
|
||||
|
|
@ -821,8 +844,8 @@ packages:
|
|||
terser:
|
||||
optional: true
|
||||
|
||||
vue-i18n@9.14.4:
|
||||
resolution: {integrity: sha512-B934C8yUyWLT0EMud3DySrwSUJI7ZNiWYsEEz2gknTthqKiG4dzWE/WSa8AzCuSQzwBEv4HtG1jZDhgzPfWSKQ==}
|
||||
vue-i18n@12.0.0-alpha.2:
|
||||
resolution: {integrity: sha512-ZSaZrDV/PhD4hLVybo84bkaNRnkGDF7GpI0Fcmn9Yj+2Kq5C3nE7I5iRbo+DiHyRGrwZ/IV1VP3naFAhcNJGsg==}
|
||||
engines: {node: '>= 16'}
|
||||
peerDependencies:
|
||||
vue: ^3.0.0
|
||||
|
|
@ -941,21 +964,28 @@ snapshots:
|
|||
'@esbuild/win32-x64@0.18.20':
|
||||
optional: true
|
||||
|
||||
'@heroicons/vue@2.2.0(vue@3.5.13)':
|
||||
'@heroicons/vue@2.2.0(vue@3.5.13(typescript@5.8.3))':
|
||||
dependencies:
|
||||
vue: 3.5.13
|
||||
vue: 3.5.13(typescript@5.8.3)
|
||||
|
||||
'@intlify/core-base@9.14.4':
|
||||
'@intlify/core-base@12.0.0-alpha.2':
|
||||
dependencies:
|
||||
'@intlify/message-compiler': 9.14.4
|
||||
'@intlify/shared': 9.14.4
|
||||
'@intlify/message-compiler': 12.0.0-alpha.2
|
||||
'@intlify/shared': 12.0.0-alpha.2
|
||||
|
||||
'@intlify/message-compiler@9.14.4':
|
||||
'@intlify/message-compiler@12.0.0-alpha.2':
|
||||
dependencies:
|
||||
'@intlify/shared': 9.14.4
|
||||
'@intlify/shared': 12.0.0-alpha.2
|
||||
source-map-js: 1.2.1
|
||||
|
||||
'@intlify/shared@9.14.4': {}
|
||||
'@intlify/shared@12.0.0-alpha.2': {}
|
||||
|
||||
'@intlify/vue-i18n-core@12.0.0-alpha.2(vue@3.5.13(typescript@5.8.3))':
|
||||
dependencies:
|
||||
'@intlify/core-base': 12.0.0-alpha.2
|
||||
'@intlify/shared': 12.0.0-alpha.2
|
||||
'@vue/devtools-api': 6.6.4
|
||||
vue: 3.5.13(typescript@5.8.3)
|
||||
|
||||
'@isaacs/cliui@8.0.2':
|
||||
dependencies:
|
||||
|
|
@ -998,10 +1028,14 @@ snapshots:
|
|||
'@pkgjs/parseargs@0.11.0':
|
||||
optional: true
|
||||
|
||||
'@vitejs/plugin-vue@4.6.2(vite@4.5.14)(vue@3.5.13)':
|
||||
'@types/node@22.15.17':
|
||||
dependencies:
|
||||
vite: 4.5.14
|
||||
vue: 3.5.13
|
||||
undici-types: 6.21.0
|
||||
|
||||
'@vitejs/plugin-vue@4.6.2(vite@4.5.14(@types/node@22.15.17))(vue@3.5.13(typescript@5.8.3))':
|
||||
dependencies:
|
||||
vite: 4.5.14(@types/node@22.15.17)
|
||||
vue: 3.5.13(typescript@5.8.3)
|
||||
|
||||
'@vue/compiler-core@3.5.13':
|
||||
dependencies:
|
||||
|
|
@ -1051,11 +1085,11 @@ snapshots:
|
|||
'@vue/shared': 3.5.13
|
||||
csstype: 3.1.3
|
||||
|
||||
'@vue/server-renderer@3.5.13(vue@3.5.13)':
|
||||
'@vue/server-renderer@3.5.13(vue@3.5.13(typescript@5.8.3))':
|
||||
dependencies:
|
||||
'@vue/compiler-ssr': 3.5.13
|
||||
'@vue/shared': 3.5.13
|
||||
vue: 3.5.13
|
||||
vue: 3.5.13(typescript@5.8.3)
|
||||
|
||||
'@vue/shared@3.5.13': {}
|
||||
|
||||
|
|
@ -1554,6 +1588,10 @@ snapshots:
|
|||
|
||||
ts-interface-checker@0.1.13: {}
|
||||
|
||||
typescript@5.8.3: {}
|
||||
|
||||
undici-types@6.21.0: {}
|
||||
|
||||
update-browserslist-db@1.1.3(browserslist@4.24.5):
|
||||
dependencies:
|
||||
browserslist: 4.24.5
|
||||
|
|
@ -1562,33 +1600,37 @@ snapshots:
|
|||
|
||||
util-deprecate@1.0.2: {}
|
||||
|
||||
vite@4.5.14:
|
||||
vite@4.5.14(@types/node@22.15.17):
|
||||
dependencies:
|
||||
esbuild: 0.18.20
|
||||
postcss: 8.5.3
|
||||
rollup: 3.29.5
|
||||
optionalDependencies:
|
||||
'@types/node': 22.15.17
|
||||
fsevents: 2.3.3
|
||||
|
||||
vue-i18n@9.14.4(vue@3.5.13):
|
||||
vue-i18n@12.0.0-alpha.2(vue@3.5.13(typescript@5.8.3)):
|
||||
dependencies:
|
||||
'@intlify/core-base': 9.14.4
|
||||
'@intlify/shared': 9.14.4
|
||||
'@intlify/core-base': 12.0.0-alpha.2
|
||||
'@intlify/shared': 12.0.0-alpha.2
|
||||
'@intlify/vue-i18n-core': 12.0.0-alpha.2(vue@3.5.13(typescript@5.8.3))
|
||||
'@vue/devtools-api': 6.6.4
|
||||
vue: 3.5.13
|
||||
vue: 3.5.13(typescript@5.8.3)
|
||||
|
||||
vue-router@4.5.1(vue@3.5.13):
|
||||
vue-router@4.5.1(vue@3.5.13(typescript@5.8.3)):
|
||||
dependencies:
|
||||
'@vue/devtools-api': 6.6.4
|
||||
vue: 3.5.13
|
||||
vue: 3.5.13(typescript@5.8.3)
|
||||
|
||||
vue@3.5.13:
|
||||
vue@3.5.13(typescript@5.8.3):
|
||||
dependencies:
|
||||
'@vue/compiler-dom': 3.5.13
|
||||
'@vue/compiler-sfc': 3.5.13
|
||||
'@vue/runtime-dom': 3.5.13
|
||||
'@vue/server-renderer': 3.5.13(vue@3.5.13)
|
||||
'@vue/server-renderer': 3.5.13(vue@3.5.13(typescript@5.8.3))
|
||||
'@vue/shared': 3.5.13
|
||||
optionalDependencies:
|
||||
typescript: 5.8.3
|
||||
|
||||
which@2.0.2:
|
||||
dependencies:
|
||||
|
|
|
|||
BIN
public/image/maps/Menu_Background.png
Normal file
|
After Width: | Height: | Size: 816 KiB |
BIN
public/image/maps/TF_AngelCity_Concept_1.jpg
Normal file
|
After Width: | Height: | Size: 94 KiB |
BIN
public/image/maps/TF_Backwater_Loadscreen.jpg
Normal file
|
After Width: | Height: | Size: 73 KiB |
BIN
public/image/maps/TF_Colony_Loadscreen.jpg
Normal file
|
After Width: | Height: | Size: 79 KiB |
BIN
public/image/maps/TF_Corporate_Loadscreen.jpg
Normal file
|
After Width: | Height: | Size: 75 KiB |
BIN
public/image/maps/TF_Demeter_Loadscreen.jpg
Normal file
|
After Width: | Height: | Size: 75 KiB |
BIN
public/image/maps/TF_Dig_Site_Loadscreen.jpg
Normal file
|
After Width: | Height: | Size: 81 KiB |
BIN
public/image/maps/TF_Export_Loadscreen.jpg
Normal file
|
After Width: | Height: | Size: 91 KiB |
BIN
public/image/maps/TF_Fracture_Loadscreen.jpg
Normal file
|
After Width: | Height: | Size: 86 KiB |
BIN
public/image/maps/TF_Haven_Loadscreen.jpg
Normal file
|
After Width: | Height: | Size: 119 KiB |
BIN
public/image/maps/TF_IMC_Rising_Keyart.jpg
Normal file
|
After Width: | Height: | Size: 124 KiB |
BIN
public/image/maps/TF_Lagoon_Loadscreen.jpg
Normal file
|
After Width: | Height: | Size: 96 KiB |
BIN
public/image/maps/TF_Nexus_Loadscreen.jpg
Normal file
|
After Width: | Height: | Size: 72 KiB |
BIN
public/image/maps/TF_Outpost207_Loadscreen.jpg
Normal file
|
After Width: | Height: | Size: 94 KiB |
BIN
public/image/maps/TF_Overlook_Loadscreen.jpg
Normal file
|
After Width: | Height: | Size: 99 KiB |
BIN
public/image/maps/TF_Relic_Loadscreen.jpg
Normal file
|
After Width: | Height: | Size: 98 KiB |
BIN
public/image/maps/TF_Rise_Loadscreen.jpg
Normal file
|
After Width: | Height: | Size: 78 KiB |
BIN
public/image/maps/TF_Runoff_Loadscreen.jpg
Normal file
|
After Width: | Height: | Size: 94 KiB |
BIN
public/image/maps/TF_Sand_Trap_Loadscreen.jpg
Normal file
|
After Width: | Height: | Size: 62 KiB |
BIN
public/image/maps/TF_Smuggler_Cove_Loadscreen.jpg
Normal file
|
After Width: | Height: | Size: 101 KiB |
BIN
public/image/maps/TF_Swampland_Loadscreen.jpg
Normal file
|
After Width: | Height: | Size: 94 KiB |
BIN
public/image/maps/TF_TrainingGround_Loadscreen.jpg
Normal file
|
After Width: | Height: | Size: 96 KiB |
BIN
public/image/maps/TF_War_Games_Loadscreen.jpg
Normal file
|
After Width: | Height: | Size: 106 KiB |
BIN
public/image/maps/TF_Zone_18_Loadscreen.jpg
Normal file
|
After Width: | Height: | Size: 63 KiB |
BIN
public/image/maps/Titanfall-Starships-Fleet-Wallpaper.jpg
Normal file
|
After Width: | Height: | Size: 80 KiB |
74
src/App.vue
|
|
@ -3,7 +3,7 @@
|
|||
<header class="bg-titanfall-secondary shadow-lg">
|
||||
<div class="container mx-auto px-4 py-6">
|
||||
<h1 class="text-3xl font-bold text-titanfall-accent">
|
||||
{{ $t('serverList.title') }}
|
||||
{{ t('serverList.title') }}
|
||||
</h1>
|
||||
</div>
|
||||
</header>
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
<input
|
||||
v-model="searchQuery"
|
||||
type="text"
|
||||
:placeholder="$t('serverList.search')"
|
||||
:placeholder="t('serverList.search')"
|
||||
class="w-full px-4 py-2 rounded-lg bg-titanfall-secondary border border-gray-700 focus:border-titanfall-accent focus:outline-none"
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -31,7 +31,7 @@
|
|||
: 'bg-titanfall-secondary hover:bg-gray-700'
|
||||
]"
|
||||
>
|
||||
{{ $t(`serverList.filter.${mode.value}`) }}
|
||||
{{ t(`serverList.filter.${mode.value}`) }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -57,19 +57,19 @@
|
|||
<div class="p-6 space-y-4 flex-grow flex flex-col">
|
||||
<div class="space-y-2">
|
||||
<p class="flex justify-between">
|
||||
<span class="text-gray-400">{{ $t('serverList.status.players') }}:</span>
|
||||
<span class="text-gray-400">{{ t('serverList.status.players') }}:</span>
|
||||
<span>{{ server.total_players }}/{{ server.max_players }}</span>
|
||||
</p>
|
||||
<p class="flex justify-between">
|
||||
<span class="text-gray-400">{{ $t('serverList.status.map') }}:</span>
|
||||
<span>{{ server.map_name }}</span>
|
||||
<span class="text-gray-400">{{ t('serverList.status.map') }}:</span>
|
||||
<span>{{ t(`serverList.map.${server.map_name}`) }}</span>
|
||||
</p>
|
||||
<p class="flex justify-between">
|
||||
<span class="text-gray-400">{{ $t('serverList.status.mode') }}:</span>
|
||||
<span>{{ $t(`serverList.filter.${server.game_mode}`) }}</span>
|
||||
<span class="text-gray-400">{{ t('serverList.status.mode') }}:</span>
|
||||
<span>{{ t(`serverList.filter.${server.game_mode}`) }}</span>
|
||||
</p>
|
||||
<p class="flex justify-between">
|
||||
<span class="text-gray-400">{{ $t('serverList.status.version') }}:</span>
|
||||
<span class="text-gray-400">{{ t('serverList.status.version') }}:</span>
|
||||
<span>{{ server.version }}</span>
|
||||
</p>
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
|
|
@ -86,11 +86,9 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="overflow-y-auto flex-grow border-t border-gray-700 py-2">
|
||||
<p class="text-sm text-gray-400">{{ server.description }}</p>
|
||||
</div>
|
||||
<div class="overflow-y-auto flex-grow border-t border-gray-700 py-2">
|
||||
<p class="text-sm text-gray-400">{{ server.description }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -98,18 +96,23 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import axios from 'axios'
|
||||
import type { Server, GameMode, GameModeOption } from './types'
|
||||
import { mapImageMapping } from './data/data'
|
||||
|
||||
const servers = ref([])
|
||||
const { t } = useI18n()
|
||||
|
||||
const servers = ref<Server[]>([])
|
||||
const searchQuery = ref('')
|
||||
const selectedMode = ref('all')
|
||||
const selectedMode = ref<GameMode>('all')
|
||||
const copiedServer = ref('')
|
||||
|
||||
const gameModes = [
|
||||
const gameModes: GameModeOption[] = [
|
||||
{ value: 'all', label: 'All' },
|
||||
{ value: 'attrition', label: 'Attrition' },
|
||||
{ value: 'at', label: 'Attrition' },
|
||||
{ value: 'campaign', label: 'Campaign' },
|
||||
{ value: 'coop', label: 'Co-op' },
|
||||
{ value: 'ctf', label: 'Capture the Flag' },
|
||||
|
|
@ -128,45 +131,20 @@ const filteredServers = computed(() => {
|
|||
})
|
||||
})
|
||||
|
||||
const fetchServers = async () => {
|
||||
const fetchServers = async (): Promise<void> => {
|
||||
try {
|
||||
const response = await axios.get('/api/servers')
|
||||
const response = await axios.get<Server[]>('/api/servers')
|
||||
servers.value = response.data
|
||||
} catch (error) {
|
||||
console.error('Error fetching servers:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const mapImageMapping = {
|
||||
'mp_angel_city': '/image/maps/TF_AngelCity_Loadscreen.jpg',
|
||||
'mp_black_water_canal': '/image/maps/TF_BlackWaterCanal_Loadscreen.jpg',
|
||||
'mp_coliseum': '/image/maps/TF_Coliseum_Loadscreen.jpg',
|
||||
'mp_colony02': '/image/maps/TF_Colony_Loadscreen.jpg',
|
||||
'mp_complex3': '/image/maps/TF_Complex_Loadscreen.jpg',
|
||||
'mp_crashsite3': '/image/maps/TF_Crashsite_Loadscreen.jpg',
|
||||
'mp_drydock': '/image/maps/TF_Drydock_Loadscreen.jpg',
|
||||
'mp_eden': '/image/maps/TF_Eden_Loadscreen.jpg',
|
||||
'mp_forwardbase_kodai': '/image/maps/TF_ForwardBaseKodai_Loadscreen.jpg',
|
||||
'mp_glitch': '/image/maps/TF_Glitch_Loadscreen.jpg',
|
||||
'mp_grave': '/image/maps/TF_Grave_Loadscreen.jpg',
|
||||
'mp_homestead': '/image/maps/TF_Homestead_Loadscreen.jpg',
|
||||
'mp_lf_deck': '/image/maps/TF_LFDeck_Loadscreen.jpg',
|
||||
'mp_lf_meadow': '/image/maps/TF_LFMeadow_Loadscreen.jpg',
|
||||
'mp_lf_stacks': '/image/maps/TF_LFStacks_Loadscreen.jpg',
|
||||
'mp_lf_township': '/image/maps/TF_LFTownship_Loadscreen.jpg',
|
||||
'mp_lf_traffic': '/image/maps/TF_LFTraffic_Loadscreen.jpg',
|
||||
'mp_lf_uma': '/image/maps/TF_LFUMA_Loadscreen.jpg',
|
||||
'mp_relic02': '/image/maps/TF_Relic_Loadscreen.jpg',
|
||||
'mp_rise': '/image/maps/TF_Rise_Loadscreen.jpg',
|
||||
'mp_thaw': '/image/maps/TF_Thaw_Loadscreen.jpg',
|
||||
'mp_wargames': '/image/maps/TF_Wargames_Loadscreen.jpg'
|
||||
}
|
||||
|
||||
const getMapImage = (mapName) => {
|
||||
const getMapImage = (mapName: string): string => {
|
||||
return mapImageMapping[mapName.toLowerCase()] || '/image/maps/default_map.jpg'
|
||||
}
|
||||
|
||||
const copyConnectCommand = async (server) => {
|
||||
const copyConnectCommand = async (server: Server): Promise<void> => {
|
||||
const command = `${server.ip}:${server.port}`
|
||||
try {
|
||||
await navigator.clipboard.writeText(command)
|
||||
|
|
|
|||
27
src/data/data.ts
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
export const mapImageMapping: Record<string, string> = {
|
||||
'mp_airbase': '/image/maps/TF_Airbase_Loadscreen.jpg',
|
||||
'mp_angel_city': '/image/maps/TF_AngelCity_Loadscreen.jpg',
|
||||
'mp_boneyard': '/image/maps/TF_Boneyard_Loadscreen.jpg',
|
||||
'mp_colony': '/image/maps/TF_Colony_Loadscreen.jpg',
|
||||
'mp_corporate': '/image/maps/TF_Corporate_Loadscreen.jpg',
|
||||
'mp_fracture': '/image/maps/TF_Fracture_Loadscreen.jpg',
|
||||
'mp_lagoon': '/image/maps/TF_Lagoon_Loadscreen.jpg',
|
||||
'mp_nexus': '/image/maps/TF_Nexus_Loadscreen.jpg',
|
||||
'mp_o2': '/image/maps/TF_Demeter_Loadscreen.jpg',
|
||||
'mp_outpost_207': '/image/maps/TF_Outpost207_Loadscreen.jpg',
|
||||
'mp_overlook': '/image/maps/TF_Overlook_Loadscreen.jpg',
|
||||
'mp_relic': '/image/maps/TF_Relic_Loadscreen.jpg',
|
||||
'mp_rise': '/image/maps/TF_Rise_Loadscreen.jpg',
|
||||
'mp_smugglers_cove': '/image/maps/TF_Smuggler_Cove_Loadscreen.jpg',
|
||||
'mp_training_ground': '/image/maps/TF_TrainingGround_Loadscreen.jpg',
|
||||
'mp_wargames': '/image/maps/TF_War_Games_Loadscreen.jpg',
|
||||
'mp_runoff': '/image/maps/TF_Runoff_Loadscreen.jpg',
|
||||
'mp_swampland': '/image/maps/TF_Swampland_Loadscreen.jpg',
|
||||
'mp_haven': '/image/maps/TF_Haven_Loadscreen.jpg',
|
||||
'mp_harmony_mines': '/image/maps/TF_Dig_Site_Loadscreen.jpg',
|
||||
'mp_switchback': '/image/maps/TF_Export_Loadscreen.jpg',
|
||||
'mp_backwater': '/image/maps/TF_Backwater_Loadscreen.jpg',
|
||||
'mp_sandtrap': '/image/maps/TF_Sand_Trap_Loadscreen.jpg',
|
||||
'mp_zone_18': '/image/maps/TF_Zone_18_Loadscreen.jpg',
|
||||
'mp_lobby': '/image/maps/Menu_Background.png',
|
||||
}
|
||||
51
src/lang/en.js
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
export default {
|
||||
serverList: {
|
||||
title: 'Titanfall Server List',
|
||||
search: 'Search servers...',
|
||||
filter: {
|
||||
all: 'All',
|
||||
at: 'Attrition',
|
||||
campaign: 'Campaign',
|
||||
coop: 'Co-op',
|
||||
ctf: 'Capture the Flag',
|
||||
lts: 'Last Titan Standing',
|
||||
mfdp: 'Marked for Death Pro',
|
||||
ps: 'Pilot Skirmish',
|
||||
tdm: 'Team Deathmatch'
|
||||
},
|
||||
map:{
|
||||
mp_airbase: 'AirBase',
|
||||
mp_angel_city: 'Angel City',
|
||||
mp_boneyard: 'Boneyard',
|
||||
mp_colony: 'Colony',
|
||||
mp_corporate: 'Corporate',
|
||||
mp_fracture: 'Fracture',
|
||||
mp_lagoon: 'Lagoon',
|
||||
mp_nexus: 'Nexus',
|
||||
mp_o2: 'Demeter',
|
||||
mp_outpost_207: 'Outpost 207',
|
||||
mp_overlook: 'Overlook',
|
||||
mp_relic: 'Relic',
|
||||
mp_rise: 'Rise',
|
||||
mp_smugglers_cove: 'Smugglers Cove',
|
||||
mp_training_ground: 'Training Ground',
|
||||
mp_wargames: 'War Games',
|
||||
mp_runoff: 'Runoff',
|
||||
mp_swampland: 'Swampland',
|
||||
mp_haven: 'Haven',
|
||||
mp_harmony_mines: 'Dig Site',
|
||||
mp_switchback: 'Export',
|
||||
mp_backwater: 'Backwater',
|
||||
mp_sandtrap: 'SandTrap',
|
||||
mp_zone_18: 'Zone18',
|
||||
mp_lobby: 'Lobby',
|
||||
},
|
||||
status: {
|
||||
players: 'Players',
|
||||
maxPlayers: 'Max Players',
|
||||
map: 'Map',
|
||||
mode: 'Mode',
|
||||
version: 'Version'
|
||||
}
|
||||
}
|
||||
}
|
||||
14
src/lang/i18n.js
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import { createI18n } from 'vue-i18n'
|
||||
import zh from './zh'
|
||||
import en from './en'
|
||||
|
||||
const i18n = createI18n({
|
||||
locale: 'zh',
|
||||
fallbackLocale: 'en',
|
||||
messages: {
|
||||
zh,
|
||||
en
|
||||
}
|
||||
})
|
||||
|
||||
export default i18n
|
||||
51
src/lang/zh.js
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
export default {
|
||||
serverList: {
|
||||
title: 'R1Delta 服务器列表(本页面开发中)',
|
||||
search: '搜索服务器...',
|
||||
filter: {
|
||||
all: '全部',
|
||||
at: '消耗战',
|
||||
campaign: '战役',
|
||||
coop: '边境防御',
|
||||
ctf: '夺旗',
|
||||
lts: '泰坦殊死战',
|
||||
mfdp: '标记死亡',
|
||||
ps: '铁驭对铁驭',
|
||||
tdm: '团队死斗'
|
||||
},
|
||||
map:{
|
||||
mp_airbase: '空军基地',
|
||||
mp_angel_city: '天使城',
|
||||
mp_boneyard: '墓地',
|
||||
mp_colony: '殖民地',
|
||||
mp_corporate: '总部',
|
||||
mp_fracture: '摧残之地',
|
||||
mp_lagoon: '泻湖',
|
||||
mp_nexus: '中枢',
|
||||
mp_o2: '穀神星',
|
||||
mp_outpost_207: '207号哨站',
|
||||
mp_overlook: '瞭望台',
|
||||
mp_relic: '遗迹',
|
||||
mp_rise: '崛起',
|
||||
mp_smugglers_cove: '走私巢穴',
|
||||
mp_training_ground: '训练场地',
|
||||
mp_wargames: '战争游戏',
|
||||
mp_runoff: '径流',
|
||||
mp_swampland: '沼泽地',
|
||||
mp_haven: '避难所',
|
||||
mp_harmony_mines: '挖掘场',
|
||||
mp_switchback: '输出港',
|
||||
mp_backwater: '荒僻之地',
|
||||
mp_sandtrap: '飞沙陷阱',
|
||||
mp_zone_18: '第18区',
|
||||
mp_lobby: '大厅',
|
||||
},
|
||||
status: {
|
||||
players: '玩家数',
|
||||
maxPlayers: '最大玩家数',
|
||||
map: '地图',
|
||||
mode: '模式',
|
||||
version: '版本'
|
||||
}
|
||||
}
|
||||
}
|
||||
56
src/main.js
|
|
@ -1,61 +1,7 @@
|
|||
import { createApp } from 'vue'
|
||||
import { createI18n } from 'vue-i18n'
|
||||
import App from './App.vue'
|
||||
import './assets/main.css'
|
||||
|
||||
const i18n = createI18n({
|
||||
locale: 'zh',
|
||||
messages: {
|
||||
zh: {
|
||||
serverList: {
|
||||
title: 'R1Delta 服务器列表(本页面开发中)',
|
||||
search: '搜索服务器...',
|
||||
filter: {
|
||||
all: '全部',
|
||||
attrition: '消耗战',
|
||||
campaign: '战役',
|
||||
coop: '合作',
|
||||
ctf: '夺旗',
|
||||
lts: '泰坦死斗',
|
||||
mfdp: '标记死亡',
|
||||
ps: '飞行员对战',
|
||||
tdm: '团队死斗'
|
||||
},
|
||||
status: {
|
||||
players: '玩家数',
|
||||
maxPlayers: '最大玩家数',
|
||||
map: '地图',
|
||||
mode: '模式',
|
||||
version: '版本'
|
||||
}
|
||||
}
|
||||
},
|
||||
en: {
|
||||
serverList: {
|
||||
title: 'Titanfall Server List',
|
||||
search: 'Search servers...',
|
||||
filter: {
|
||||
all: 'All',
|
||||
attrition: 'Attrition',
|
||||
campaign: 'Campaign',
|
||||
coop: 'Co-op',
|
||||
ctf: 'Capture the Flag',
|
||||
lts: 'Last Titan Standing',
|
||||
mfdp: 'Marked for Death Pro',
|
||||
ps: 'Pilot Skirmish',
|
||||
tdm: 'Team Deathmatch'
|
||||
},
|
||||
status: {
|
||||
players: 'Players',
|
||||
maxPlayers: 'Max Players',
|
||||
map: 'Map',
|
||||
mode: 'Mode',
|
||||
version: 'Version'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
import i18n from './lang/i18n'
|
||||
|
||||
const app = createApp(App)
|
||||
app.use(i18n)
|
||||
|
|
|
|||
18
src/types/index.ts
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
export interface Server {
|
||||
ip: string;
|
||||
port: number;
|
||||
host_name: string;
|
||||
description: string;
|
||||
map_name: string;
|
||||
game_mode: GameMode;
|
||||
total_players: number;
|
||||
max_players: number;
|
||||
version: string;
|
||||
}
|
||||
|
||||
export type GameMode = 'all' | 'at' | 'campaign' | 'coop' | 'ctf' | 'lts' | 'mfdp' | 'ps' | 'tdm';
|
||||
|
||||
export interface GameModeOption {
|
||||
value: GameMode;
|
||||
label: string;
|
||||
}
|
||||
25
tsconfig.json
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"useDefineForClassFields": true,
|
||||
"module": "ESNext",
|
||||
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
||||
"skipLibCheck": true,
|
||||
|
||||
/* Bundler mode */
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
"jsx": "preserve",
|
||||
|
||||
/* Linting */
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
|
||||
"references": [{ "path": "./tsconfig.node.json" }]
|
||||
}
|
||||
10
tsconfig.node.json
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"skipLibCheck": true,
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "bundler",
|
||||
"allowSyntheticDefaultImports": true
|
||||
},
|
||||
"include": ["vite.config.ts"]
|
||||
}
|
||||