Skip to content

Commit

Permalink
v1.5 正式发布
Browse files Browse the repository at this point in the history
  • Loading branch information
Hikari committed Oct 3, 2024
1 parent 37baa99 commit 9d24e38
Show file tree
Hide file tree
Showing 20 changed files with 396 additions and 245 deletions.
5 changes: 1 addition & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,4 @@ test*.py
.ssh/
.cache/
.idea/
pack.py
b64.txt
templates.zip
templates.py
hsl-config.json
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Hikari Server Launcher is a simple, lightweight, and easy-to-use launcher/instal
## Contributing 贡献
- 你可以从两方面对此项目贡献:
- 提交 issue, pull request 来完善这个项目。
- 编辑configs.json,这是特定配置的索引文件,个人时间有限无法全部适配,configs.json的格式可以参考 [config.json](https://github.com/Hikari16665/HikariServerLauncher/blob/main/spconfigs.json),里面有详细的注释。
- 编辑spconfigs.json,这是特定配置的索引文件,个人时间有限无法全部适配,spconfigs.json的格式可以参考 [spconfig.json](https://github.com/Hikari16665/HikariServerLauncher/blob/main/spconfigs.json),里面有详细的注释。


## 致谢 Thanks
Expand Down
4 changes: 2 additions & 2 deletions hsl-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
"use_mirror": true,
"workspace_dir": "workspace",
"workspace_file": "workspace.json",
"autorun": "1",
"debug": false
"autorun": "",
"debug": true
}
3 changes: 2 additions & 1 deletion hsl/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from . import core
from . import utils
from . import gametypes
from . import gametypes
from . import source
29 changes: 29 additions & 0 deletions hsl/core/checks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import logging
import requests
from hsl.source.source import Source
logger = logging.getLogger(__name__)
DOWNLOAD_SOURCE = r'https://hsl.hikari.bond/source.json'
SPCONFIGS_SOURCE = r'https://hsl.hikari.bond/spconfigs.json'
VERSION_SOURCE = r'https://hsl.hikari.bond/hsl.json'

def make_request(url: str, error_message: str) -> dict:
try:
response = requests.get(url)
if response.status_code == 200:
return response.json()
logger.error(f'{error_message},状态码:{response.status_code}')
return {}
except Exception as e:
logger.error(f'{error_message},错误信息:{e}')
return {}
def check_update(version: int) -> tuple[bool, int]:
data = make_request(VERSION_SOURCE, error_message='检查更新失败')
latest: int = data.get('version', 0)
return (True, latest) if version < latest else (False, version)
def load_source() -> Source:
"""Load source data from sources
"""
_source = make_request(DOWNLOAD_SOURCE, error_message='加载源数据失败')
return Source(**_source)
def get_spconfigs():
return make_request(SPCONFIGS_SOURCE, error_message='加载特定配置文件失败')
2 changes: 2 additions & 0 deletions hsl/core/exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class NoSuchServerException(Exception):
pass
22 changes: 12 additions & 10 deletions hsl/core/java.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ async def getJavaVersion(self,mcVersion: str) -> str:
return '21'
else:
return '0'
async def checkJavaExist(self,javaVersion,path) -> bool:
async def checkJavaExist(self,javaVersion: str,path: str) -> bool:
"""
Check if Java exists.
Args:
Expand All @@ -65,10 +65,12 @@ async def checkJavaExist(self,javaVersion,path) -> bool:
bool: True if the java exists, False otherwise.
"""

if not os.path.exists(os.path.join(path, 'java', javaVersion, 'bin', JAVA_EXEC)):
return False
return True
async def downloadJava(self, javaVersion, path) -> bool:
return bool(
os.path.exists(
os.path.join(path, 'java', javaVersion, 'bin', JAVA_EXEC)
)
)
async def downloadJava(self, javaVersion: str, path: str) -> bool:
"""
Download Java and return the status.
Expand All @@ -79,7 +81,7 @@ async def downloadJava(self, javaVersion, path) -> bool:
Returns:
bool: True if the java is downloaded and extracted successfully, False otherwise.
"""
sources = self.source['java']['list']
sources = self.source.java.list
if self.config.use_mirror:
sources = sources[::-1]
path = os.path.join(path,'java',javaVersion)
Expand All @@ -90,9 +92,9 @@ async def downloadJava(self, javaVersion, path) -> bool:
#get source
for i in sources:
if os.name == 'nt':
url = i['windows'][javaVersion]
if os.name == 'posix':
url = i['linux'][javaVersion]
url = i.windows[javaVersion]
elif os.name == 'posix':
url = i.linux[javaVersion]
if await downloadfile(url,filename):
with zipfile.ZipFile(filename,'r') as file:
file.extractall(path)
Expand Down Expand Up @@ -120,7 +122,7 @@ async def getJavaByGameVersion(self, mcVersion: str, path: str) -> str:
await self.downloadJava(javaVersion, path)
return os.path.join(javaPath, 'bin', JAVA_EXEC)

async def getJavaByJavaVersion(self, javaVersion:str, path:str) -> str:
async def getJavaByJavaVersion(self, javaVersion: str, path:str) -> str:
"""
get java path by java version(if not exist, will call downloadJava)
Expand Down
41 changes: 9 additions & 32 deletions hsl/core/main.py
Original file line number Diff line number Diff line change
@@ -1,43 +1,20 @@
from hsl.core.config import Config
from hsl.core.checks import load_source, get_spconfigs, check_update
from rich.console import Console
import logging
import requests
import sys
import platform
console = Console()
HSL_VERSION = 15
DOWNLOAD_SOURCE = r'https://hsl.hikari.bond/source.json'
SPCONFIGS_SOURCE = r'https://hsl.hikari.bond/spconfigs.json'
VERSION_SOURCE = r'https://hsl.hikari.bond/hsl.json'
logger = logging.getLogger(__name__)
def make_request(url: str, error_message: str) -> dict:
try:
response = requests.get(url)
if response.status_code == 200:
print(response.json())
return response.json()
else:
logger.error(f'{error_message},状态码:{response.status_code}')
return {}
except Exception as e:
logger.error(f'{error_message},错误信息:{e}')
return {}
def check_update(version: int) -> tuple[bool, int]:
data = make_request(VERSION_SOURCE, error_message='检查更新失败')
latest: int = data.get('version', 0)
if version < latest:
return True, latest
return False, version
def load_source() -> dict:
"""Load source data from sources
"""
return make_request(DOWNLOAD_SOURCE, error_message='加载源数据失败')
def get_spconfigs():
return make_request(SPCONFIGS_SOURCE, error_message='加载特定配置文件失败')

OS_ARCH = platform.machine()
if OS_ARCH != 'AMD64':
console.print(f'当前系统架构{OS_ARCH}不支持,请使用AMD64架构的设备/系统运行.')
sys.exit(1)

console.rule('加载信息中,请稍后...')
SOURCE = load_source()
SPCONFIGS = get_spconfigs()
VERSIONINFO = check_update(HSL_VERSION)
VERSION_INFO = check_update(HSL_VERSION)

class HSL:
"""Main class of HSL
Expand All @@ -47,7 +24,7 @@ def __init__(self):
self.config = Config().load()
self.source = SOURCE
self.spconfigs = SPCONFIGS
self.flag_outdated, self.latest_version = VERSIONINFO
self.flag_outdated, self.latest_version = VERSION_INFO
if not self.source or not self.spconfigs:
console.print('加载源数据失败,请检查网络连接.')
sys.exit(1)
Expand Down
78 changes: 59 additions & 19 deletions hsl/core/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import psutil
import asyncio
import subprocess

from hsl.core.java import Java
from hsl.core.main import HSL
from queue import Queue
from rich.live import Live
Expand All @@ -20,12 +20,14 @@ class Server(HSL):
"""
Server Class
"""
def __init__(self, *, name: str, type: str, path: str, javaPath: str, maxRam: str, data={}):
def __init__(self, *, name: str, type: str, path: str, javaversion: str, maxRam: str, data=None):
if data is None:
data = {}
super().__init__()
self.name = name
self.type = type
self.path = path
self.javaPath = javaPath
self.javaversion = javaversion
self.maxRam = maxRam
self.data = data

Expand Down Expand Up @@ -111,44 +113,81 @@ def consoleInput(self, process, input_queue: Queue):
asyncio.set_event_loop(loop)
loop.run_until_complete(self.get_input(process, input_queue))

def check_process(self, process):
def check_process_exists(self, process):
return psutil.pid_exists(process.pid)

def gen_run_command(self, export: bool = False) -> str:
javaexecPath = self.javaPath if os.name != 'posix' else (r'./../../' + self.javaPath if not self.config.direct_mode else r'./' + self.javaPath)

async def gen_run_command(self, path, export: bool = False) -> str:
console.log(f'[Debug]: Path: {path}')
console.log(f'[Debug]: javaversion: {self.javaversion}')
javaexecPath = await Java().getJavaByJavaVersion(self.javaversion, path)

if export:
run_dir = os.getcwd()
javaexecPath = os.path.join(run_dir, javaexecPath)
run_command = self._build_run_command(javaexecPath, export=True)
return f'cd {os.path.join(os.getcwd(), self.path)}\n{run_command}'
return "\n".join([
"cd " + os.path.join(os.getcwd(), self.path),
run_command
])

return self._build_run_command(javaexecPath)

def _build_run_command(self, javaexecPath, export=False):
jvm_setting = self.data.get('jvm_setting', '')

if self.type in ['vanilla', 'paper', 'fabric']:
return f'{javaexecPath} -Dfile.encoding=utf-8 -Xmx{self.maxRam} -jar {self.pathJoin("server.jar")}' if export else f'{javaexecPath} -Dfile.encoding=utf-8 -Xmx{self.maxRam} -jar server.jar'

return " ".join([
javaexecPath,
"-Dfile.encoding=utf-8",
"-Xmx" + self.maxRam,
"-jar",
self.pathJoin("server.jar") if export else "server.jar"
])

mcVersion = self.data['mcVersion']
forgeVersion = self.data['forgeVersion']
mcMajorVersion = int(mcVersion.split('.')[1])

if mcMajorVersion >= 17:
args_path = f"@{self.pathJoin(f'libraries/net/minecraftforge/forge/{mcVersion}-{forgeVersion}/unix_args.txt')}" if os.name == 'posix' else f"@{self.pathJoin(f'libraries/net/minecraftforge/forge/{mcVersion}-{forgeVersion}/win_args.txt')}"
args_path = (
"@" + self.pathJoin(f"libraries/net/minecraftforge/forge/{mcVersion}-{forgeVersion}/unix_args.txt")
if os.name == 'posix'
else "@" + self.pathJoin(f"libraries/net/minecraftforge/forge/{mcVersion}-{forgeVersion}/win_args.txt")
)

if jvm_setting:
console.log(f'[Debug]: Jvm Setting: {jvm_setting}')
return f'{javaexecPath}{jvm_setting} -Dfile.encoding=utf-8 -Xmx{self.maxRam} @user_jvm_args.txt {args_path} %*'
return f'{javaexecPath} -Dfile.encoding=utf-8 -Xmx{self.maxRam} @user_jvm_args.txt {args_path} '

return f'{javaexecPath} -Dfile.encoding=utf-8 -Xmx{self.maxRam} -jar {self.pathJoin(f"forge-{mcVersion}-{forgeVersion}.jar")}' if export else f'{javaexecPath} -Dfile.encoding=utf-8 -Xmx{self.maxRam} -jar forge-{mcVersion}-{forgeVersion}.jar'

async def run(self):
return " ".join([
javaexecPath + jvm_setting,
"-Dfile.encoding=utf-8",
"-Xmx" + self.maxRam,
"@user_jvm_args.txt",
args_path,
"%*"
])

return " ".join([
javaexecPath,
"-Dfile.encoding=utf-8",
"-Xmx" + self.maxRam,
"@user_jvm_args.txt",
args_path
])

return " ".join([
javaexecPath,
"-Dfile.encoding=utf-8",
"-Xmx" + self.maxRam,
"-jar",
self.pathJoin(f"forge-{mcVersion}-{forgeVersion}.jar")
if export else f"forge-{mcVersion}-{forgeVersion}.jar"
])

async def run(self, path: str):
if 'startup_cmd' in self.data:
subprocess.Popen(self.data['startup_cmd'], cwd=self.path)

run_command = self.gen_run_command()
run_command = await self.gen_run_command(path)

if self.config.debug:
console.log(f'[Debug]: Run Command: {run_command}')
Expand All @@ -174,4 +213,5 @@ async def run(self):
t1.join()
console.print('[bold green]请输入任意内容以退出控制台')
t2.join()
console.print('[bold green]控制台已退出')
return
23 changes: 12 additions & 11 deletions hsl/core/workspace.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from hsl.core.exceptions import NoSuchServerException
from hsl.core.main import HSL
import json
import os
Expand All @@ -24,7 +25,7 @@ def save(self):
json.dump(self.workspaces, f)
def load(self):
with open(self.path, 'r') as f:
self.workspaces = json.load(f)
self.workspaces: list[dict] = json.load(f)
async def create(self, *, server_name: str):
serverPath = os.path.join(self.dir,server_name)
if not os.path.exists(serverPath):
Expand All @@ -37,20 +38,20 @@ async def add(self, Server: Server):
"name": Server.name,
"type": Server.type,
"path": Server.path,
"javaPath": Server.javaPath,
"javaversion": Server.javaversion,
"maxRam": Server.maxRam,
"data": Server.data
})
self.save()
async def get(self, index: int) -> Server:
server = self.workspaces[index]
return Server(
name = server["name"],
type = server["type"],
path = server["path"],
javaPath = server["javaPath"],
maxRam = server["maxRam"],
data = server["data"]
name = server.get("name",''),
type = server.get("type",''),
path = server.get("path",''),
javaversion = server.get("javaversion",''),
maxRam = server.get("maxRam",''),
data = server.get("data",{})
)
async def getFromName(self, name: str) -> Server:
for server in self.workspaces:
Expand All @@ -59,15 +60,15 @@ async def getFromName(self, name: str) -> Server:
name = server["name"],
type = server["type"],
path = server["path"],
javaPath = server["javaPath"],
javaversion = server["javaversion"],
maxRam = server["maxRam"],
data = server["data"]
)
raise Exception("Server not found")
raise NoSuchServerException("Server not found")
async def delete(self, index: int):
try:
shutil.rmtree(self.workspaces[index]["path"])
except:
except Exception:
pass
del self.workspaces[index]
self.save()
Expand Down
Loading

0 comments on commit 9d24e38

Please sign in to comment.