mirror of
https://gitlab.com/crafty-controller/crafty-4.git
synced 2025-01-18 17:15:13 +01:00
Merge branch 'dev' into tweak/serverjars-bedrock
This commit is contained in:
commit
1fd4a50828
@ -7,6 +7,8 @@ TBD
|
|||||||
- Send empty json for no banned/cached players ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/589))
|
- Send empty json for no banned/cached players ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/589))
|
||||||
- Bump Tornado from 6.0 to 6.3.2 in response to CVE-2023-28370 ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/591))
|
- Bump Tornado from 6.0 to 6.3.2 in response to CVE-2023-28370 ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/591))
|
||||||
- Fix bug where commands would show "command_server" when initially created ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/592))
|
- Fix bug where commands would show "command_server" when initially created ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/592))
|
||||||
|
### Refactor
|
||||||
|
- Optimize player management page ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/593))
|
||||||
### Tweaks
|
### Tweaks
|
||||||
TBD
|
TBD
|
||||||
### Lang
|
### Lang
|
||||||
|
@ -11,6 +11,7 @@ import subprocess
|
|||||||
import html
|
import html
|
||||||
import urllib.request
|
import urllib.request
|
||||||
import glob
|
import glob
|
||||||
|
import json
|
||||||
|
|
||||||
from zoneinfo import ZoneInfo
|
from zoneinfo import ZoneInfo
|
||||||
|
|
||||||
@ -132,6 +133,15 @@ class ServerInstance:
|
|||||||
self.server_object = HelperServers.get_server_obj(self.server_id)
|
self.server_object = HelperServers.get_server_obj(self.server_id)
|
||||||
self.stats_helper = HelperServerStats(self.server_id)
|
self.stats_helper = HelperServerStats(self.server_id)
|
||||||
self.last_backup_failed = False
|
self.last_backup_failed = False
|
||||||
|
try:
|
||||||
|
with open(
|
||||||
|
os.path.join(self.server_object.path, "db_stats", "players_cache.json"),
|
||||||
|
"r",
|
||||||
|
encoding="utf-8",
|
||||||
|
) as f:
|
||||||
|
self.player_cache = list(json.load(f).values())
|
||||||
|
except:
|
||||||
|
self.player_cache = []
|
||||||
try:
|
try:
|
||||||
self.tz = get_localzone()
|
self.tz = get_localzone()
|
||||||
except ZoneInfoNotFoundError as e:
|
except ZoneInfoNotFoundError as e:
|
||||||
@ -770,6 +780,7 @@ class ServerInstance:
|
|||||||
)
|
)
|
||||||
if self.settings["stop_command"]:
|
if self.settings["stop_command"]:
|
||||||
self.send_command(self.settings["stop_command"])
|
self.send_command(self.settings["stop_command"])
|
||||||
|
self.write_player_cache()
|
||||||
else:
|
else:
|
||||||
# windows will need to be handled separately for Ctrl+C
|
# windows will need to be handled separately for Ctrl+C
|
||||||
self.process.terminate()
|
self.process.terminate()
|
||||||
@ -1218,6 +1229,40 @@ class ServerInstance:
|
|||||||
)
|
)
|
||||||
update_thread.start()
|
update_thread.start()
|
||||||
|
|
||||||
|
def write_player_cache(self):
|
||||||
|
write_json = {}
|
||||||
|
for item in self.player_cache:
|
||||||
|
write_json[item["name"]] = item
|
||||||
|
with open(
|
||||||
|
os.path.join(self.server_path, "db_stats", "players_cache.json"),
|
||||||
|
"w",
|
||||||
|
encoding="utf-8",
|
||||||
|
) as f:
|
||||||
|
f.write(json.dumps(write_json, indent=4))
|
||||||
|
logger.info("Cache file refreshed")
|
||||||
|
|
||||||
|
def cache_players(self):
|
||||||
|
server_players = self.get_server_players()
|
||||||
|
for p in self.player_cache[:]:
|
||||||
|
if p["status"] == "Online" and p["name"] not in server_players:
|
||||||
|
p["status"] = "Offline"
|
||||||
|
p["last_seen"] = datetime.datetime.now().strftime("%d/%m/%Y %H:%M")
|
||||||
|
elif p["name"] in server_players:
|
||||||
|
self.player_cache.remove(p)
|
||||||
|
for player in server_players:
|
||||||
|
if player == "Anonymous Player":
|
||||||
|
# Skip Anonymous Player
|
||||||
|
continue
|
||||||
|
if player in self.player_cache:
|
||||||
|
self.player_cache.remove(player)
|
||||||
|
self.player_cache.append(
|
||||||
|
{
|
||||||
|
"name": player,
|
||||||
|
"status": "Online",
|
||||||
|
"last_seen": datetime.datetime.now().strftime("%d/%m/%Y %H:%M"),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
def check_update(self):
|
def check_update(self):
|
||||||
return self.stats_helper.get_server_stats()["updating"]
|
return self.stats_helper.get_server_stats()["updating"]
|
||||||
|
|
||||||
@ -1404,6 +1449,12 @@ class ServerInstance:
|
|||||||
minutes=self.helper.get_setting("dir_size_poll_freq_minutes"),
|
minutes=self.helper.get_setting("dir_size_poll_freq_minutes"),
|
||||||
id=str(self.server_id) + "_dir_poll",
|
id=str(self.server_id) + "_dir_poll",
|
||||||
)
|
)
|
||||||
|
self.dir_scheduler.add_job(
|
||||||
|
self.cache_players,
|
||||||
|
"interval",
|
||||||
|
seconds=5,
|
||||||
|
id=str(self.server_id) + "_players_poll",
|
||||||
|
)
|
||||||
|
|
||||||
def calc_dir_size(self):
|
def calc_dir_size(self):
|
||||||
server_dt = HelperServers.get_server_data_by_id(self.server_id)
|
server_dt = HelperServers.get_server_data_by_id(self.server_id)
|
||||||
@ -1473,6 +1524,7 @@ class ServerInstance:
|
|||||||
"created": datetime.datetime.now().strftime(
|
"created": datetime.datetime.now().strftime(
|
||||||
"%Y/%m/%d, %H:%M:%S"
|
"%Y/%m/%d, %H:%M:%S"
|
||||||
),
|
),
|
||||||
|
"players_cache": self.player_cache,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
total_players += int(raw_ping_result.get("online"))
|
total_players += int(raw_ping_result.get("online"))
|
||||||
|
@ -781,24 +781,11 @@ class PanelHandler(BaseHandler):
|
|||||||
page_data[
|
page_data[
|
||||||
"banned_players"
|
"banned_players"
|
||||||
] = self.controller.servers.get_banned_players(server_id)
|
] = self.controller.servers.get_banned_players(server_id)
|
||||||
page_data[
|
server_instance = self.controller.servers.get_server_instance_by_id(
|
||||||
"cached_players"
|
server_id
|
||||||
] = self.controller.servers.get_cached_players(server_id)
|
)
|
||||||
|
page_data["cached_players"] = server_instance.player_cache
|
||||||
|
|
||||||
page_data["all_players"] = []
|
|
||||||
for player in page_data["cached_players"]:
|
|
||||||
if player["name"] in page_data["get_players"]:
|
|
||||||
player["status"] = "online"
|
|
||||||
else:
|
|
||||||
player["status"] = "offline"
|
|
||||||
temp_date = datetime.datetime.strptime(
|
|
||||||
player["expiresOn"], "%Y-%m-%d %H:%M:%S %z"
|
|
||||||
)
|
|
||||||
player["last_seen"] = (
|
|
||||||
temp_date - datetime.timedelta(30, 0, 0, 0, 0, 0, 0)
|
|
||||||
).strftime("%Y/%m/%d %H:%M:%S")
|
|
||||||
player["avatar"] = Helpers.get_player_avatar(player["uuid"])
|
|
||||||
page_data["all_players"].append(player)
|
|
||||||
for player in page_data["banned_players"]:
|
for player in page_data["banned_players"]:
|
||||||
player["banned"] = True
|
player["banned"] = True
|
||||||
temp_date = datetime.datetime.strptime(
|
temp_date = datetime.datetime.strptime(
|
||||||
|
@ -228,6 +228,24 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
initParser('input_motd', 'input_motd');
|
initParser('input_motd', 'input_motd');
|
||||||
|
let text = ""
|
||||||
|
let players = server.players_cache;
|
||||||
|
for(let i=0; i < players.length; i++){
|
||||||
|
text += `<tr id="playerItem-${ players[i]["name"] }" class="playerItem--" style="text-align: center;">`;
|
||||||
|
text += `<td class="no-scroll" style="overflow: scroll;"><strong>${players[i]["name"]}</strong></td>`;
|
||||||
|
if(players[i]["status"] === "Online"){
|
||||||
|
text += `<td><span class="text-success"><i class="fas fa-signal"></i> ${ players[i]['status'] }</span></td>`
|
||||||
|
}else{
|
||||||
|
text += `<td><span class="text-warning"><i class="fa-regular fa-circle-xmark"></i><span class="offline-status"> ${ players[i]['status'] }</span><span class="conn-break"> Last connection :<br> ${ players[i]['last_seen'] }</span></td>`
|
||||||
|
}
|
||||||
|
if(server["running"]){
|
||||||
|
text += `<td><button onclick="send_command_to_server('ban ${ players[i]['name'] }')" type="button" class="btn btn-danger controls">Ban</button><br class="mobile-break"><button onclick="send_command_to_server('kick ${ players[i]['name'] }')" type="button" class="btn btn-outline-danger controls">Kick</button><br><button onclick="send_command_to_server('op ${ players[i]['name'] }')" type="button" class="btn btn-warning controls">OP</button><br class="mobile-break"><button onclick="send_command_to_server('deop ${ players[i]['name'] }')" type="button" class="btn btn-outline-warning controls">De-OP</button></td>`
|
||||||
|
}else{
|
||||||
|
text += `<td><span> Unavailable<br> (Server Offline)</span></td>`
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
$("#player-body").html(text);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<div class="col-md-6 col-sm-12">
|
<div class="col-xl-6 col-lg-12 col-md-12 col-sm-12">
|
||||||
<h2>{{ translate('serverPlayerManagement', 'players', data['lang']) }}:</h2>
|
<h2>{{ translate('serverPlayerManagement', 'players', data['lang']) }}:</h2>
|
||||||
<table class="table table-sm-responsive">
|
<table class="table table-sm-responsive">
|
||||||
<thead class="thead">
|
<thead class="thead">
|
||||||
@ -8,25 +8,28 @@
|
|||||||
<th scope="col">Actions</th>
|
<th scope="col">Actions</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody id="player-body">
|
||||||
{% for player in data['all_players'] %}
|
{% for player in data['cached_players'] %}
|
||||||
<tr id="playerItem-{{ player['name'] }}" class="playerItem--">
|
<tr id="playerItem-{{ player['name'] }}" class="playerItem--" style="text-align: center;">
|
||||||
<td>
|
<td>
|
||||||
<strong> {{ player['name'] }}</strong>
|
<strong> {{ player['name'] }}</strong>
|
||||||
</td>
|
</td>
|
||||||
{% if player['status'] == 'online' %}
|
{% if player['status'] == 'Online' %}
|
||||||
<td><span class="text-success"><i class="fas fa-signal"></i> {{ player['status'] }}</span></td>
|
<td style="overflow: scroll;"><span class="text-success"><i class="fas fa-signal"></i> {{ player['status'] }}</span></td>
|
||||||
{% elif player['status'] == 'offline' %}
|
{% elif player['status'] == 'Offline' %}
|
||||||
<td><span class="text-warning"><i class="fa-solid fa-signal-slash"></i> Last connection : {{ player['last_seen'] }}</span></td>
|
<td><span class="text-warning"><i class="fa-regular fa-circle-xmark"></i><span class="offline-status"> {{ player['status'] }}</span><span class="conn-break"> Last connection :<br> {{ player['last_seen'] }}</span></span></td>
|
||||||
{% end %}
|
{% end %}
|
||||||
<td class="buttons">
|
<td class="buttons" style="text-align: center;">
|
||||||
{% if data['server_stats']['running'] %}
|
{% if data['server_stats']['running'] %}
|
||||||
<button onclick="send_command_to_server(`ban {{ player['name'] }}`)" type="button" class="btn btn-danger">Ban</button>
|
<button onclick="send_command_to_server(`ban {{ player['name'] }}`)" type="button" class="btn btn-danger controls">Ban</button>
|
||||||
<button onclick="send_command_to_server(`kick {{ player['name'] }}`)" type="button" class="btn btn-outline-danger">Kick</button>
|
<br class="mobile-break"/>
|
||||||
<button onclick="send_command_to_server(`op {{ player['name'] }}`)" type="button" class="btn btn-warning">OP</button>
|
<button onclick="send_command_to_server(`kick {{ player['name'] }}`)" type="button" class="btn btn-outline-danger controls">Kick</button>
|
||||||
<button onclick="send_command_to_server(`deop {{ player['name'] }}`)" type="button" class="btn btn-outline-warning">De-OP</button>
|
<br>
|
||||||
|
<button onclick="send_command_to_server(`op {{ player['name'] }}`)" type="button" class="btn btn-warning controls">OP</button>
|
||||||
|
<br class="mobile-break"/>
|
||||||
|
<button onclick="send_command_to_server(`deop {{ player['name'] }}`)" type="button" class="btn btn-outline-warning controls">De-OP</button>
|
||||||
{% else %}
|
{% else %}
|
||||||
<span> Unavailable (Server Offline)</span>
|
<span> Unavailable <br>(Server Offline)</span>
|
||||||
{% end %}
|
{% end %}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -34,9 +37,23 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6 col-sm-12">
|
<style>
|
||||||
|
@media (min-width: 600px) {
|
||||||
|
.mobile-break { display: none;}
|
||||||
|
.offline-status {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media screen and (max-width: 600px) {
|
||||||
|
.conn-break { display: none; }
|
||||||
|
}
|
||||||
|
button.controls {
|
||||||
|
width: 70px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div class="col-xl-6 col-lg-12 col-md-12 col-sm-12 no-scroll" width="100%">
|
||||||
<h2>{{ translate('serverPlayerManagement', 'bannedPlayers', data['lang']) }}:</h2>
|
<h2>{{ translate('serverPlayerManagement', 'bannedPlayers', data['lang']) }}:</h2>
|
||||||
<table class="table table-sm-responsive">
|
<table class="table table-sm-responsive d-none d-lg-block no-scroll" style="width: 100%;">
|
||||||
<thead class="thead">
|
<thead class="thead">
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col">Player</th>
|
<th scope="col">Player</th>
|
||||||
@ -58,4 +75,22 @@
|
|||||||
{% end %}
|
{% end %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
<table class="table table-sm-responsive d-block d-lg-none" style="width: 100%;">
|
||||||
|
<thead class="thead ">
|
||||||
|
<tr>
|
||||||
|
<th scope="col">Player</th>
|
||||||
|
<th scope="col">Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for player in data['banned_players'] %}
|
||||||
|
<tr id="playerItem-{{ player }}" class="playerItem--">
|
||||||
|
<td><strong> {{ player['name'] }}</strong></td>
|
||||||
|
<td class="buttons">
|
||||||
|
<button onclick="send_command_to_server(`pardon {{ player['name'] }} `)" type="button" class="btn btn-danger">Unban</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% end %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
Loading…
x
Reference in New Issue
Block a user