Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Beta22 #29

Merged
merged 20 commits into from
Jan 27, 2024
5 changes: 3 additions & 2 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ var defaultConfig = Config{
BackupPath: "",
Address: "127.0.0.1",
ProcessName: "PalServer",
ServerOptions: []string{"-useperfthreads"," -NoAsyncLoadingThread", "-UseMultithreadForDS"},
ServerOptions: []string{"-useperfthreads", "-NoAsyncLoadingThread", "-UseMultithreadForDS"},
CheckInterval: 30, // 30 秒
WebuiPort: "52000", // Webui 端口号
AutolaunchWebui: true,
Expand Down Expand Up @@ -189,12 +189,13 @@ func checkAndSetDefaults(config *Config) bool {
for i := 0; i < val.NumField(); i++ {
field := val.Field(i)
defaultField := reflect.ValueOf(defaultConfig).Field(i)
fieldType := field.Type()

// 跳过布尔类型的字段
if fieldType.Kind() == reflect.Bool {
continue
}

fieldName := typ.Field(i).Name

// 特殊处理MemoryCleanupInterval字段
Expand Down
135 changes: 135 additions & 0 deletions front/palworld-front/src/components/PlayerManage.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
<template>
<q-page padding>
<q-btn icon="refresh" color="primary" @click="loadPlayers" class="q-mb-md"
>刷新</q-btn
>
<div v-if="loading">加载中...</div>
<div v-else>
<q-list bordered separator>
<q-item
v-for="player in sortedPlayers"
:key="player.playeruid"
clickable
@click="selectPlayer(player)"
>
<q-item-section avatar>
<q-icon
name="online_prediction"
v-if="player.online"
color="green"
/>
</q-item-section>
<q-item-section>
<div class="text-h6">
{{ player.online ? '【在线】' : '' }} {{ player.name }}
</div>
<div>上次在线时间: {{ player.last_online }}</div>
<div>playeruid: {{ player.playeruid }}</div>
<div>steamid: {{ player.steamid }}</div>
</q-item-section>
<q-item-section side>
<q-btn
flat
color="red"
icon="block"
@click.stop="kickOrBan(player, 'kick')"
>踢出</q-btn
>
<q-btn
flat
color="orange"
icon="gavel"
@click.stop="kickOrBan(player, 'ban')"
>封禁</q-btn
>
<q-btn
flat
color="blue"
icon="content_copy"
@click.stop="copyToClipboard(player.playeruid)"
>复制UID</q-btn
>
<q-btn
flat
color="blue"
icon="content_copy"
@click.stop="copyToClipboard(player.steamid)"
>复制SteamID</q-btn
>
</q-item-section>
</q-item>
</q-list>
</div>
</q-page>
</template>

<script setup lang="ts">
import { ref, onMounted, computed } from 'vue';
import { useQuasar } from 'quasar';
import axios from 'axios';

interface Player {
last_online: string;
name: string;
online: boolean;
playeruid: string;
steamid: string;
}

const players = ref<Player[]>([]);
const loading = ref(true);
const $q = useQuasar();

const loadPlayers = async () => {
loading.value = true;
try {
const response = await axios.get('/api/player?update=true');
players.value = response.data;
} catch (error) {
console.error('API 请求失败', error);
$q.notify({ type: 'negative', message: '加载失败' });
} finally {
loading.value = false;
}
};

onMounted(loadPlayers);

const sortedPlayers = computed(() => {
// 使用 slice() 创建 players 数组的副本,然后进行排序
return players.value
.slice()
.sort((a, b) => Number(b.online) - Number(a.online));
});

const selectPlayer = (player: Player) => {
// 记录选中的playeruid和steamid
console.log('选中的玩家:', player);
};

const kickOrBan = async (player: Player, type: 'kick' | 'ban') => {
try {
await axios.post('/api/kickorban', {
playeruid: player.playeruid,
steamid: player.steamid,
type: type,
});
$q.notify({
type: 'positive',
message: `${type === 'kick' ? '踢出' : '封禁'}成功`,
});
} catch (error) {
$q.notify({ type: 'negative', message: '操作失败' });
}
};

const copyToClipboard = (text: string) => {
navigator.clipboard.writeText(text).then(() => {
$q.notify({ type: 'positive', message: '复制成功' });
});
};
</script>

<style scoped lang="scss">
/* 可以添加自定义样式 */
</style>
80 changes: 79 additions & 1 deletion front/palworld-front/src/pages/IndexView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<q-tab name="guard" label="守护配置修改" />
<q-tab name="server" label="服务端配置修改" />
<q-tab name="command" label="服务器指令" />
<q-tab name="player-manage" label="玩家管理" />
<q-tab name="advanced" label="高级配置修改" @click="redirectToSav" />
<q-tab name="server-check" label="服务器检测" />
</q-tabs>
Expand Down Expand Up @@ -35,7 +36,25 @@
<q-input
filled
v-model="config.maintenanceWarningMessage"
label="维护警告消息"
label="维护公告消息(英文)"
class="q-my-md"
/>
<q-input
filled
v-model="config.gamePath"
label="游戏服务端exe路径"
class="q-my-md"
/>
<q-input
filled
v-model="config.gameSavePath"
label="游戏存档路径"
class="q-my-md"
/>
<q-input
filled
v-model="config.backupPath"
label="游戏存档备份存放路径"
class="q-my-md"
/>

Expand All @@ -54,6 +73,13 @@
label="内存占用检测时间(秒)"
class="q-my-md"
/>
<q-input
filled
v-model.number="config.checkInterval"
type="number"
label="进程存活检测时间(秒)"
class="q-my-md"
/>
<q-input
filled
v-model.number="config.memoryCleanupInterval"
Expand All @@ -68,6 +94,13 @@
label="消息广播周期(秒)"
class="q-my-md"
/>
<q-input
filled
v-model.number="config.memoryUsageThreshold"
type="number"
label="服务端重启内存阈值(百分比)"
class="q-my-md"
/>
<q-input
filled
v-model.number="config.totalMemoryGB"
Expand Down Expand Up @@ -105,6 +138,36 @@
/>
</div>

<!-- 数组类型的配置项:启动参数数组 -->
<div class="q-my-md">
<div class="text-h6">服务端启动参数</div>
<div
v-for="(message, index) in config.serverOptions"
:key="index"
class="q-mb-sm"
>
<q-input
filled
v-model="config.serverOptions[index]"
label="启动参数"
dense
/>
<q-btn
flat
icon="delete"
@click="removeMessageServerOptions(index)"
class="q-ml-md"
/>
</div>
<q-btn
flat
icon="add"
@click="addMessageServerOptions"
label="添加参数"
class="q-mt-md"
/>
</div>

<!-- 保存按钮 -->
<q-btn
color="primary"
Expand Down Expand Up @@ -565,6 +628,10 @@
</div>
</div>
</q-page>
<!-- 玩家管理组件 -->
<q-page padding v-if="tab === 'player-manage'">
<player-manage />
</q-page>
<q-page padding v-if="tab === 'server-check'">
<div class="text-h6">服务器检测页面</div>
<running-process-status
Expand All @@ -581,6 +648,7 @@
import axios from 'axios';
import { QPage, QCard, QCardSection } from 'quasar';
import RunningProcessStatus from 'components/RunningProcessStatus.vue';
import PlayerManage from 'components/PlayerManage.vue';

//给components传递数据
const props = defineProps({
Expand All @@ -600,11 +668,11 @@
const showDifficultyTooltip = ref(false);
const showDeathPenaltyTooltip = ref(false);

const toggleTooltip = (type) => {

Check warning on line 671 in front/palworld-front/src/pages/IndexView.vue

View workflow job for this annotation

GitHub Actions / Build on linux for amd64

'type' is defined but never used

Check warning on line 671 in front/palworld-front/src/pages/IndexView.vue

View workflow job for this annotation

GitHub Actions / Build on linux for arm64

'type' is defined but never used

Check warning on line 671 in front/palworld-front/src/pages/IndexView.vue

View workflow job for this annotation

GitHub Actions / Build on darwin for amd64

'type' is defined but never used

Check warning on line 671 in front/palworld-front/src/pages/IndexView.vue

View workflow job for this annotation

GitHub Actions / Build on darwin for arm64

'type' is defined but never used

Check warning on line 671 in front/palworld-front/src/pages/IndexView.vue

View workflow job for this annotation

GitHub Actions / Build on windows for amd64

'type' is defined but never used
showDeathPenaltyTooltip.value = !showDeathPenaltyTooltip.value;
};

const toggleTooltip2 = (type) => {

Check warning on line 675 in front/palworld-front/src/pages/IndexView.vue

View workflow job for this annotation

GitHub Actions / Build on linux for amd64

'type' is defined but never used

Check warning on line 675 in front/palworld-front/src/pages/IndexView.vue

View workflow job for this annotation

GitHub Actions / Build on linux for arm64

'type' is defined but never used

Check warning on line 675 in front/palworld-front/src/pages/IndexView.vue

View workflow job for this annotation

GitHub Actions / Build on darwin for amd64

'type' is defined but never used

Check warning on line 675 in front/palworld-front/src/pages/IndexView.vue

View workflow job for this annotation

GitHub Actions / Build on darwin for arm64

'type' is defined but never used

Check warning on line 675 in front/palworld-front/src/pages/IndexView.vue

View workflow job for this annotation

GitHub Actions / Build on windows for amd64

'type' is defined but never used
showDifficultyTooltip.value = !showDifficultyTooltip.value;
};

Expand Down Expand Up @@ -637,6 +705,16 @@
config.value.regularMessages.splice(index, 1);
};

// 增加一个消息到数组
const addMessageServerOptions = () => {
config.value.ServerOptions.push('');
};

// 从数组中移除一个消息
const removeMessageServerOptions = (index) => {
config.value.ServerOptions.splice(index, 1);
};

onMounted(async () => {
try {
const response = await axios.get('/api/getjson');
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ require (
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
github.com/yusufpapurcu/wmi v1.2.3 // indirect
go.etcd.io/bbolt v1.3.8
golang.org/x/arch v0.3.0 // indirect
golang.org/x/crypto v0.14.0 // indirect
golang.org/x/sys v0.15.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4d
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw=
github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
go.etcd.io/bbolt v1.3.8 h1:xs88BrvEv273UsB79e0hcVrlUWmS0a8upikMFhSyAtA=
go.etcd.io/bbolt v1.3.8/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw=
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k=
golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
Expand Down
32 changes: 27 additions & 5 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,18 @@ import (
"time"

"github.com/gin-gonic/gin"
"go.etcd.io/bbolt"

"github.com/hoshinonyaruko/palworld-go/config"
"github.com/hoshinonyaruko/palworld-go/sys"
"github.com/hoshinonyaruko/palworld-go/tool"
"github.com/hoshinonyaruko/palworld-go/webui"
)

var version string

var db *bbolt.DB

//go:embed RAMMap64.exe
var rammapFS embed.FS

Expand All @@ -43,15 +49,23 @@ func main() {
}
//cookie数据库
webui.InitializeDB()
//玩家数据库
db = webui.InitDB()
//启动周期任务
go tool.ScheduleTask(db, jsonconfig)
if db == nil {
log.Fatal("Failed to initialize database")
}
defer db.Close()
r := gin.Default()
//webui和它的api
webuiGroup := r.Group("/")
{
webuiGroup.GET("/*filepath", webui.CombinedMiddleware(jsonconfig))
webuiGroup.POST("/*filepath", webui.CombinedMiddleware(jsonconfig))
webuiGroup.PUT("/*filepath", webui.CombinedMiddleware(jsonconfig))
webuiGroup.DELETE("/*filepath", webui.CombinedMiddleware(jsonconfig))
webuiGroup.PATCH("/*filepath", webui.CombinedMiddleware(jsonconfig))
webuiGroup.GET("/*filepath", webui.CombinedMiddleware(jsonconfig, db))
webuiGroup.POST("/*filepath", webui.CombinedMiddleware(jsonconfig, db))
webuiGroup.PUT("/*filepath", webui.CombinedMiddleware(jsonconfig, db))
webuiGroup.DELETE("/*filepath", webui.CombinedMiddleware(jsonconfig, db))
webuiGroup.PATCH("/*filepath", webui.CombinedMiddleware(jsonconfig, db))
}
// 创建一个http.Server实例(主服务器)
httpServer := &http.Server{
Expand Down Expand Up @@ -85,6 +99,14 @@ func main() {
OpenWebUI(&jsonconfig)
}

latestTag, err := sys.GetLatestTag("sanaefox/palworld-go")
if err != nil {
fmt.Println("Error fetching latest tag:", err)
return
}

fmt.Printf("当前版本: %s 最新版本: %s \n", version, latestTag)

if runtime.GOOS == "windows" {
if jsonconfig.MemoryCleanupInterval != 0 {
log.Printf("你决定使用rammap清理内存....这不会导致游戏卡顿\n")
Expand Down
Loading
Loading