optional custom icon per server

This commit is contained in:
Patrick Haßel 2025-07-30 13:38:52 +02:00
parent 24c0199160
commit 2b6468d142
5 changed files with 37 additions and 18 deletions

View File

@ -1,39 +1,27 @@
import {Mode} from "./Mode"; import {Mode} from "./Mode";
import {orNull, validateBoolean, validateNumber, validateString} from "../crud/CrudHelpers"; import {validateBoolean, validateNumber, validateString} from "../crud/CrudHelpers";
export class Server { export class Server {
constructor( constructor(
readonly directory: string,
readonly name: string, readonly name: string,
readonly motd: string, readonly motd: string,
readonly mode: Mode, readonly mode: Mode,
readonly serverPort: number, readonly serverPort: number,
readonly rconPort: number,
readonly rconPassword: string,
readonly queryPort: number,
readonly pid: number | null,
readonly running: boolean, readonly running: boolean,
readonly propertyFile: string, readonly hasIcon: boolean,
readonly pidFile: string,
) { ) {
// //
} }
static fromJson(json: any): Server { static fromJson(json: any): Server {
return new Server( return new Server(
validateString(json.directory),
validateString(json.name), validateString(json.name),
validateString(json.motd), validateString(json.motd),
validateString(json.mode) as Mode, validateString(json.mode) as Mode,
validateNumber(json.serverPort), validateNumber(json.serverPort),
validateNumber(json.rconPort),
validateString(json.rconPassword),
validateNumber(json.queryPort),
orNull(json.pid, validateNumber),
validateBoolean(json.running), validateBoolean(json.running),
validateString(json.propertyFile), validateBoolean(json.hasIcon),
validateString(json.pidFile),
); );
} }

View File

@ -10,7 +10,8 @@
<div class="list"> <div class="list">
<div *ngFor="let server of servers()" class="server"> <div *ngFor="let server of servers()" class="server">
<div class="icon"> <div class="icon">
<img src="{{server.mode.toLowerCase()}}.png" alt="{{server.mode}}"> <img src="{{server.mode.toLowerCase()}}.png" alt="{{server.mode}}" *ngIf="!server.hasIcon">
<img [src]="url('http',['Server', server.name, 'icon'])" alt="{{server.mode}}" *ngIf="server.hasIcon">
</div> </div>
<div class="name"> <div class="name">
{{ server.motd }} {{ server.motd }}

View File

@ -1,19 +1,23 @@
import {Component} from '@angular/core'; import {Component} from '@angular/core';
import {NgForOf} from '@angular/common'; import {NgForOf, NgIf} from '@angular/common';
import {Server} from './Server'; import {Server} from './Server';
import {CrudListComponent} from '../crud/CrudListComponent'; import {CrudListComponent} from '../crud/CrudListComponent';
import {ServerService} from './server.service'; import {ServerService} from './server.service';
import {url} from '../crud/CrudHelpers';
@Component({ @Component({
selector: 'app-server-list', selector: 'app-server-list',
imports: [ imports: [
NgForOf NgForOf,
NgIf
], ],
templateUrl: './server-list.component.html', templateUrl: './server-list.component.html',
styleUrl: './server-list.component.less' styleUrl: './server-list.component.less'
}) })
export class ServerListComponent extends CrudListComponent<Server, ServerService> { export class ServerListComponent extends CrudListComponent<Server, ServerService> {
protected readonly url = url;
constructor( constructor(
crudService: ServerService, crudService: ServerService,
) { ) {

View File

@ -1,5 +1,6 @@
package de.ph87.mc.server; package de.ph87.mc.server;
import com.fasterxml.jackson.annotation.JsonIgnore;
import de.ph87.mc.websocket.IWebsocketMessage; import de.ph87.mc.websocket.IWebsocketMessage;
import jakarta.annotation.Nullable; import jakarta.annotation.Nullable;
import lombok.Data; import lombok.Data;
@ -11,12 +12,15 @@ import java.io.File;
public class Server implements IWebsocketMessage { public class Server implements IWebsocketMessage {
@NonNull @NonNull
@JsonIgnore
public final File directory; public final File directory;
@NonNull @NonNull
@JsonIgnore
public final File propertyFile; public final File propertyFile;
@NonNull @NonNull
@JsonIgnore
public final File pidFile; public final File pidFile;
@NonNull @NonNull
@ -30,13 +34,21 @@ public class Server implements IWebsocketMessage {
public final int serverPort; public final int serverPort;
@JsonIgnore
public final int rconPort; public final int rconPort;
@NonNull @NonNull
@JsonIgnore
public final String rconPassword; public final String rconPassword;
@JsonIgnore
public final int queryPort; public final int queryPort;
@JsonIgnore
public final File iconFile;
public final boolean hasIcon;
@Nullable @Nullable
private Long pid; private Long pid;
@ -44,6 +56,7 @@ public class Server implements IWebsocketMessage {
this.directory = directory; this.directory = directory;
this.propertyFile = new File(directory, "server.properties"); this.propertyFile = new File(directory, "server.properties");
this.pidFile = new File(directory, "pid"); this.pidFile = new File(directory, "pid");
this.iconFile = new File(directory, "McManagerIcon.png");
this.name = name; this.name = name;
this.motd = motd; this.motd = motd;
this.mode = mode; this.mode = mode;
@ -51,6 +64,7 @@ public class Server implements IWebsocketMessage {
this.rconPort = rconPort; this.rconPort = rconPort;
this.rconPassword = rconPassword; this.rconPassword = rconPassword;
this.queryPort = queryPort; this.queryPort = queryPort;
this.hasIcon = iconFile.isFile();
} }
@Override @Override

View File

@ -1,5 +1,6 @@
package de.ph87.mc.server; package de.ph87.mc.server;
import jakarta.servlet.http.HttpServletResponse;
import lombok.NonNull; import lombok.NonNull;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.CrossOrigin;
@ -8,6 +9,8 @@ import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.List; import java.util.List;
@CrossOrigin @CrossOrigin
@ -35,4 +38,13 @@ public class ServerController {
return serverService.stop(name); return serverService.stop(name);
} }
@GetMapping("{name}/icon")
public void icon(@NonNull @PathVariable final String name, @NonNull final HttpServletResponse response) throws IOException {
final Server server = serverRepository.getByName(name);
try (final FileInputStream inputStream = new FileInputStream(server.iconFile)) {
response.getOutputStream().write(inputStream.readAllBytes());
}
response.getOutputStream().flush();
}
} }