finish implementation
This commit is contained in:
parent
a17e0452a0
commit
23d93a7f9a
8 changed files with 90 additions and 55 deletions
|
@ -4,6 +4,7 @@ import 'package:libac_dart/packets/packets.dart';
|
||||||
import 'package:libac_dart/utils/IOTools.dart';
|
import 'package:libac_dart/utils/IOTools.dart';
|
||||||
import 'package:servermanager/game.dart';
|
import 'package:servermanager/game.dart';
|
||||||
import 'package:servermanager/packets/ClientPackets.dart';
|
import 'package:servermanager/packets/ClientPackets.dart';
|
||||||
|
import 'package:servermanager/structs/SessionData.dart';
|
||||||
import 'package:servermanager/structs/settings.dart';
|
import 'package:servermanager/structs/settings.dart';
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
|
@ -73,7 +74,12 @@ void main() async {
|
||||||
|
|
||||||
print("Starting up server manager server wrapper");
|
print("Starting up server manager server wrapper");
|
||||||
|
|
||||||
await PacketServer.start(settings.inst?.serverSettings.WrapperPort ?? 25306);
|
while (!SessionData.shutdownPending) {
|
||||||
|
try {
|
||||||
|
await PacketServer.start(
|
||||||
|
settings.inst?.serverSettings.WrapperPort ?? 25306);
|
||||||
|
} catch (E) {}
|
||||||
|
}
|
||||||
|
|
||||||
print("Server stopping");
|
print("Server stopping");
|
||||||
}
|
}
|
||||||
|
|
|
@ -289,26 +289,33 @@ class C2SUploadSettingsPacket implements IPacket {
|
||||||
@override
|
@override
|
||||||
Future<PacketResponse> handleServerPacket() async {
|
Future<PacketResponse> handleServerPacket() async {
|
||||||
Settings settings = Settings();
|
Settings settings = Settings();
|
||||||
settings.deserialize(srvSettings);
|
|
||||||
settings.Write();
|
|
||||||
|
|
||||||
// Check if server is running, if not, stop immediately
|
CompoundTag currentSettings = settings.serialize();
|
||||||
// If server is running, schedule restart for 1 minute and send a alert to all players, then perform stop or restart depending on if running in Pterodactyl Compatibility mode
|
try {
|
||||||
SessionData.shutdownMessage = "Server wrapper updated. Restart required.";
|
settings.deserialize(srvSettings);
|
||||||
SessionData.timer.apply(60);
|
settings.Write();
|
||||||
SessionData.CURRENT_INTERVAL = WarnIntervals.NONE;
|
|
||||||
|
|
||||||
if (settings.subsys.currentState == States.Inactive) {
|
// Check if server is running, if not, stop immediately
|
||||||
Timer.periodic(Duration(seconds: 10), (timer) {
|
// If server is running, schedule restart for 1 minute and send a alert to all players, then perform stop or restart depending on if running in Pterodactyl Compatibility mode
|
||||||
SessionData.shutdownPending = true;
|
SessionData.shutdownMessage = "Server wrapper updated. Restart required.";
|
||||||
// Stop packet server
|
SessionData.timer.apply(60);
|
||||||
PacketServer.socket!.close();
|
SessionData.CURRENT_INTERVAL = WarnIntervals.NONE;
|
||||||
timer.cancel();
|
|
||||||
exit(0);
|
if (settings.subsys.currentState == States.Inactive) {
|
||||||
}); // We give time to allow the server to shut down gracefully.
|
Timer.periodic(Duration(seconds: 10), (timer) {
|
||||||
|
SessionData.shutdownPending = true;
|
||||||
|
// Stop packet server
|
||||||
|
PacketServer.socket!.close();
|
||||||
|
timer.cancel();
|
||||||
|
exit(0);
|
||||||
|
}); // We give time to allow the server to shut down gracefully.
|
||||||
|
}
|
||||||
|
|
||||||
|
return PacketResponse.nil;
|
||||||
|
} catch (E) {
|
||||||
|
settings.deserialize(currentSettings);
|
||||||
|
return PacketResponse.nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
return PacketResponse.nil;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -11,16 +11,16 @@ class DiscordConfigPage extends StatefulWidget {
|
||||||
class DiscordConfigurationState extends State<DiscordConfigPage> {
|
class DiscordConfigurationState extends State<DiscordConfigPage> {
|
||||||
TextEditingController ServerNameController = TextEditingController();
|
TextEditingController ServerNameController = TextEditingController();
|
||||||
TextEditingController URLController = TextEditingController();
|
TextEditingController URLController = TextEditingController();
|
||||||
|
bool enabled = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void didChangeDependencies() {
|
void didChangeDependencies() {
|
||||||
Settings settings = Settings();
|
Settings settings = Settings();
|
||||||
final discord = settings.inst!.discord;
|
final discord = settings.inst!.discord;
|
||||||
|
|
||||||
if (discord != null) {
|
ServerNameController.text = discord.serverName;
|
||||||
ServerNameController.text = discord.serverName;
|
URLController.text = discord.url;
|
||||||
URLController.text = discord.url;
|
enabled = discord.enabled;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -37,7 +37,8 @@ class DiscordConfigurationState extends State<DiscordConfigPage> {
|
||||||
"Discord Webhook has been successfully reset and will no longer be used")));
|
"Discord Webhook has been successfully reset and will no longer be used")));
|
||||||
|
|
||||||
Settings settings = Settings();
|
Settings settings = Settings();
|
||||||
settings.inst!.discord = null;
|
settings.inst!.discord =
|
||||||
|
DiscordHookProps(url: "", serverName: "", enabled: false);
|
||||||
|
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
},
|
},
|
||||||
|
@ -50,7 +51,8 @@ class DiscordConfigurationState extends State<DiscordConfigPage> {
|
||||||
context,
|
context,
|
||||||
DiscordHookProps(
|
DiscordHookProps(
|
||||||
url: URLController.text,
|
url: URLController.text,
|
||||||
serverName: ServerNameController.text));
|
serverName: ServerNameController.text,
|
||||||
|
enabled: enabled));
|
||||||
},
|
},
|
||||||
child: Text("Submit"),
|
child: Text("Submit"),
|
||||||
),
|
),
|
||||||
|
@ -82,6 +84,14 @@ class DiscordConfigurationState extends State<DiscordConfigPage> {
|
||||||
controller: URLController,
|
controller: URLController,
|
||||||
))
|
))
|
||||||
],
|
],
|
||||||
|
),
|
||||||
|
SwitchListTile(
|
||||||
|
value: enabled,
|
||||||
|
onChanged: (V) {
|
||||||
|
enabled = V;
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
title: Text("Enabled"),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import '../structs/autorestarts.dart';
|
import '../structs/autorestarts.dart';
|
||||||
|
import '../structs/discordHookHelper.dart';
|
||||||
import '../structs/serversettings.dart';
|
import '../structs/serversettings.dart';
|
||||||
import '../structs/settings.dart';
|
import '../structs/settings.dart';
|
||||||
|
|
||||||
|
@ -80,6 +81,23 @@ class GameServerPageState extends State<GameServerPage> {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
ListTile(
|
||||||
|
title: Text("Discord WebHook"),
|
||||||
|
onTap: () async {
|
||||||
|
var response =
|
||||||
|
await Navigator.pushNamed(context, "/server/discord");
|
||||||
|
|
||||||
|
if (response == null)
|
||||||
|
return;
|
||||||
|
else {
|
||||||
|
DiscordHookProps editResult = response as DiscordHookProps;
|
||||||
|
Settings settings = Settings();
|
||||||
|
settings.inst!.discord = editResult;
|
||||||
|
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
SwitchListTile(
|
SwitchListTile(
|
||||||
value: settings.inst!.pterodactylMode,
|
value: settings.inst!.pterodactylMode,
|
||||||
onChanged: (B) {
|
onChanged: (B) {
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:servermanager/structs/discordHookHelper.dart';
|
|
||||||
import 'package:servermanager/structs/settings.dart';
|
|
||||||
|
|
||||||
import '../structs/serversettings.dart';
|
import '../structs/serversettings.dart';
|
||||||
|
|
||||||
|
@ -108,28 +106,6 @@ class ServerSettingsState extends State<ServerSettingsPage> {
|
||||||
)),
|
)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
ListTile(
|
|
||||||
title: Text("Discord WebHook"),
|
|
||||||
onTap: () async {
|
|
||||||
var response =
|
|
||||||
await Navigator.pushNamed(context, "/server/discord");
|
|
||||||
|
|
||||||
if (response == null)
|
|
||||||
return;
|
|
||||||
else {
|
|
||||||
DiscordHookProps editResult =
|
|
||||||
response as DiscordHookProps;
|
|
||||||
Settings settings = Settings();
|
|
||||||
settings.inst!.discord = editResult;
|
|
||||||
|
|
||||||
setState(() {});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
|
|
|
@ -359,6 +359,18 @@ class StateMachine {
|
||||||
print(
|
print(
|
||||||
"Scheduling restart for mod updates: ${updatedMods.join(', ')}");
|
"Scheduling restart for mod updates: ${updatedMods.join(', ')}");
|
||||||
SessionData.enableRestartTimer = true;
|
SessionData.enableRestartTimer = true;
|
||||||
|
|
||||||
|
// Send discord alert!
|
||||||
|
DiscordHookHelper.sendWebHook(
|
||||||
|
settings.inst!.discord,
|
||||||
|
DiscordHookProps.ALERT_INTRUSIVE,
|
||||||
|
"Mods have been updated",
|
||||||
|
"The server is going to restart because the following mods have been updated: \n${updatedMods.join(', ')}");
|
||||||
|
DiscordHookHelper.sendWebHook(
|
||||||
|
settings.inst!.discord,
|
||||||
|
DiscordHookProps.ALERT,
|
||||||
|
"Server Restart Alert",
|
||||||
|
"The server will restart in 5 minutes");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
|
import 'package:libac_dart/nbt/NbtUtils.dart';
|
||||||
import 'package:libac_dart/nbt/impl/CompoundTag.dart';
|
import 'package:libac_dart/nbt/impl/CompoundTag.dart';
|
||||||
import 'package:libac_dart/nbt/impl/StringTag.dart';
|
import 'package:libac_dart/nbt/impl/StringTag.dart';
|
||||||
|
|
||||||
class DiscordHookHelper {
|
class DiscordHookHelper {
|
||||||
static Future<void> sendWebHook(DiscordHookProps? props, int colorCode,
|
static Future<void> sendWebHook(DiscordHookProps props, int colorCode,
|
||||||
String title, String content) async {
|
String title, String content) async {
|
||||||
if (props == null) return; // The webhook setting is not yet set up
|
if (!props.enabled) return; // The webhook setting is not yet set up
|
||||||
var js = json.encode({
|
var js = json.encode({
|
||||||
"content": "",
|
"content": "",
|
||||||
"embeds": [
|
"embeds": [
|
||||||
|
@ -29,13 +30,16 @@ class DiscordHookHelper {
|
||||||
class DiscordHookProps {
|
class DiscordHookProps {
|
||||||
String url;
|
String url;
|
||||||
String serverName;
|
String serverName;
|
||||||
|
bool enabled = false;
|
||||||
|
|
||||||
DiscordHookProps({required this.url, required this.serverName});
|
DiscordHookProps(
|
||||||
|
{required this.url, required this.serverName, required this.enabled});
|
||||||
|
|
||||||
CompoundTag serialize() {
|
CompoundTag serialize() {
|
||||||
CompoundTag ct = CompoundTag();
|
CompoundTag ct = CompoundTag();
|
||||||
ct.put(TAG_URL, StringTag.valueOf(url));
|
ct.put(TAG_URL, StringTag.valueOf(url));
|
||||||
ct.put(TAG_SERVER_NAME, StringTag.valueOf(serverName));
|
ct.put(TAG_SERVER_NAME, StringTag.valueOf(serverName));
|
||||||
|
NbtUtils.writeBoolean(ct, TAG_ENABLED, enabled);
|
||||||
|
|
||||||
return ct;
|
return ct;
|
||||||
}
|
}
|
||||||
|
@ -43,12 +47,14 @@ class DiscordHookProps {
|
||||||
static DiscordHookProps deserialize(CompoundTag ct) {
|
static DiscordHookProps deserialize(CompoundTag ct) {
|
||||||
return DiscordHookProps(
|
return DiscordHookProps(
|
||||||
url: ct.get(TAG_URL)!.asString(),
|
url: ct.get(TAG_URL)!.asString(),
|
||||||
serverName: ct.get(TAG_SERVER_NAME)!.asString());
|
serverName: ct.get(TAG_SERVER_NAME)!.asString(),
|
||||||
|
enabled: NbtUtils.readBoolean(ct, TAG_ENABLED));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const String TAG_URL = "url";
|
static const String TAG_URL = "url";
|
||||||
static const String TAG_SERVER_NAME = "serverName";
|
static const String TAG_SERVER_NAME = "serverName";
|
||||||
static const String TAG_NAME = "discord";
|
static const String TAG_NAME = "discord";
|
||||||
|
static const String TAG_ENABLED = "enabled";
|
||||||
|
|
||||||
static const int ONLINE_ALERT = 1869056;
|
static const int ONLINE_ALERT = 1869056;
|
||||||
static const int OFFLINE_ALERT = 8716288;
|
static const int OFFLINE_ALERT = 8716288;
|
||||||
|
|
|
@ -11,7 +11,8 @@ import 'package:servermanager/structs/serversettings.dart';
|
||||||
|
|
||||||
class SettingsEntry {
|
class SettingsEntry {
|
||||||
List<Mod> mods = [];
|
List<Mod> mods = [];
|
||||||
DiscordHookProps? discord;
|
DiscordHookProps discord =
|
||||||
|
DiscordHookProps(url: "", serverName: "", enabled: false);
|
||||||
Credentials? steam_creds;
|
Credentials? steam_creds;
|
||||||
bool pterodactylMode = true; // Default is to be compatible
|
bool pterodactylMode = true; // Default is to be compatible
|
||||||
AutomaticRestartInfo timer =
|
AutomaticRestartInfo timer =
|
||||||
|
@ -61,8 +62,7 @@ class SettingsEntry {
|
||||||
}
|
}
|
||||||
tag.put("mods", lMods);
|
tag.put("mods", lMods);
|
||||||
|
|
||||||
if (discord != null)
|
tag.put(DiscordHookProps.TAG_NAME, discord.serialize());
|
||||||
tag.put(DiscordHookProps.TAG_NAME, discord!.serialize());
|
|
||||||
|
|
||||||
return tag;
|
return tag;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue