Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions Common/Configuration/ConfigContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class ConfigContainer

public class HttpServerConfig
{
public string BindAddress { get; set; } = "0.0.0.0";
public string BindAddress { get; set; } = "127.0.0.1";
public string PublicAddress { get; set; } = "127.0.0.1";
public int Port { get; set; } = 21500;
public bool EnableLog { get; set; } = false;
Expand All @@ -31,7 +31,7 @@ public string GetBindDisplayAddress()

public class GameServerConfig
{
public string BindAddress { get; set; } = "0.0.0.0";
public string BindAddress { get; set; } = "127.0.0.1";
public string PublicAddress { get; set; } = "127.0.0.1";
public int Port { get; set; } = 21000;
public int KcpAliveMs { get; set; } = 45000;
Expand Down Expand Up @@ -86,7 +86,9 @@ public class ServerProfile
public class ProxyOptions
{
public bool Enabled { get; set; } = true;
public string BindAddress { get; set; } = "127.0.0.1";
public int Port { get; set; } = 8888;
public string ServerHttpAddress { get; set; } = "127.0.0.1";
public int ServerHttpPort { get; set; } = 21500;
public bool InstallRootCertificate { get; set; } = true;
public bool ManageSystemProxy { get; set; } = true;
Expand Down
16 changes: 15 additions & 1 deletion Common/Internationalization/Message/LanguageCHS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ public class CommandTextCHS
public GirlTextCHS Girl { get; } = new();
public GiveAllTextCHS GiveAll { get; } = new();
public DebugTextCHS Debug { get; } = new();
public GmMenuTextCHS GmMenu { get; } = new();
}

#endregion
Expand Down Expand Up @@ -227,12 +228,14 @@ public class GirlTextCHS
public string Usage =>
"用法: /girl add <detail/-1> -p<particular> -l<level> -s<star>\n" +
"用法: /girl level <guid/-1> <level>\n" +
"用法: /girl neuronic <guid/-1> <level>";
"用法: /girl neuronic <guid/-1> <level>\n" +
"用法: /girl manifestation <guid/-1> <level>";

public string NotFound => "角色不存在!";
public string Added => "已为玩家添加 {0} 个角色!";
public string UpdateLevel => "已将 {1} 个角色等级设置为 {0}!";
public string UpdateNeuronicLevel => "已将 {1} 个角色的神经元等级设置为 {0}!";
public string UpdateManifestationLevel => "已将 {1} 个角色的天启/武格等级设置为 {0}!";
}

/// <summary>
Expand Down Expand Up @@ -268,6 +271,17 @@ public class DebugTextCHS
public string FileDisabled => "个人调试文件输出已禁用。";
}

/// <summary>
/// path: Game.Command.GmMenu
/// </summary>
public class GmMenuTextCHS
{
public string Desc => "切换GM选单";
public string Usage => "用法: /gm [on|off]";
public string Enabled => "已启用GM选单。";
public string Disabled => "已禁用GM选单。";
}

#endregion

#endregion
16 changes: 15 additions & 1 deletion Common/Internationalization/Message/LanguageCHT.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ public class CommandTextCHT
public GirlTextCHT Girl { get; } = new();
public GiveAllTextCHT GiveAll { get; } = new();
public DebugTextCHT Debug { get; } = new();
public GmMenuTextCHT GmMenu { get; } = new();
}

#endregion
Expand Down Expand Up @@ -227,12 +228,14 @@ public class GirlTextCHT
public string Usage =>
"用法: /girl add <detail/-1> -p<particular> -l<level> -s<star>\n" +
"用法: /girl level <guid/-1> <level>\n" +
"用法: /girl neuronic <guid/-1> <level>";
"用法: /girl neuronic <guid/-1> <level>\n" +
"用法: /girl manifestation <guid/-1> <level>";

public string NotFound => "角色不存在!";
public string Added => "已為玩家新增 {0} 個角色!";
public string UpdateLevel => "已將 {1} 個角色等級設為 {0}!";
public string UpdateNeuronicLevel => "已將 {1} 個角色的神經元等級設置為 {0}!";
public string UpdateManifestationLevel => "已将 {1} 个角色的天啟/武格等级设置为 {0}!";
}

/// <summary>
Expand Down Expand Up @@ -268,6 +271,17 @@ public class DebugTextCHT
public string FileDisabled => "個人調試檔案輸出已停用。";
}

/// <summary>
/// path: Game.Command.GmMenu
/// </summary>
public class GmMenuTextCHT
{
public string Desc => "切換GM選單";
public string Usage => "用法: /gm [on|off]";
public string Enabled => "已啟用GM選單。";
public string Disabled => "已停用GM選單。";
}

#endregion

#endregion
17 changes: 16 additions & 1 deletion Common/Internationalization/Message/LanguageEN.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ public class CommandTextEN
public GirlTextEN Girl { get; } = new();
public GiveAllTextEN GiveAll { get; } = new();
public DebugTextEN Debug { get; } = new();
public GmMenuTextEN GmMenu { get; } = new();
}

#endregion
Expand Down Expand Up @@ -193,12 +194,15 @@ public class GirlTextEN
public string Usage =>
"Usage: /girl add <detail/-1> -p<particular> -l<level> -s<star>\n" +
"Usage: /girl level <guid/-1> <level>\n" +
"Usage: /girl neuronic <guid/-1> <level>";
"Usage: /girl neuronic <guid/-1> <level>\n" +
"Usage: /girl manifestation <guid/-1> <level>";

public string NotFound => "Character not found!";
public string Added => "Granted {0} character(s) to player!";
public string UpdateLevel => "Set {1} character(s) to level {0}!";
public string UpdateNeuronicLevel => "Set {1} character(s) Neuronic to level {0}!";

public string UpdateManifestationLevel => "Set {1} character(s) Manifestation to level {0}!";
}

/// <summary>
Expand Down Expand Up @@ -234,6 +238,17 @@ public class DebugTextEN
public string FileDisabled => "Personal debug file output disabled.";
}

/// <summary>
/// path: Game.Command.GmMenu
/// </summary>
public class GmMenuTextEN
{
public string Desc => "Toggle GM menu";
public string Usage => "Usage: /gm [on|off]";
public string Enabled => "GM menu enabled.";
public string Disabled => "GM menu disabled.";
}

#endregion

#endregion
37 changes: 37 additions & 0 deletions GameServer/Command/Commands/CommandGirl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,4 +129,41 @@ await arg.SendMsg(I18NManager.Translate("Game.Command.Girl.UpdateNeuronicLevel",
level.ToString(),
girls.Count.ToString()));
}

[CommandMethod("manifestation")]
public async ValueTask UpdateManifestationLevel(CommandArg arg)
{
if (!await arg.CheckOnlineTarget()) return;
if (!await arg.CheckArgCnt(2)) return;

var guid = arg.GetInt(0);
var level = Math.Clamp(arg.GetInt(1), 0, 45);
var player = arg.Target!.Player!;
List<CharacterInfo> girls = [];

if (guid == -1)
{
foreach (var girl in player.CharacterManager.CharacterData.Characters)
{
girl.Break = (uint)level;
girls.Add(girl);
}
}
else
{
var girl = player.CharacterManager.GetCharacterByGUID((uint)guid);
if (girl == null)
{
await arg.SendMsg(I18NManager.Translate("Game.Command.Girl.NotFound"));
return;
}
girl.Break = (uint)level;
girls.Add(girl);
}

if (girls.Count > 0) await player.SendPacket(new PacketNtfCallScript(girls));
await arg.SendMsg(I18NManager.Translate("Game.Command.Girl.UpdateManifestationLevel",
level.ToString(),
girls.Count.ToString()));
}
}
50 changes: 50 additions & 0 deletions GameServer/Command/Commands/CommandGmMenu.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using MikuSB.Configuration;
using MikuSB.Enums.Player;
using MikuSB.Util;
using MikuSB.Internationalization;
using System.Text.Json.Nodes;

namespace MikuSB.GameServer.Command.Commands;

[CommandInfo("gm", "Game.Command.GmMenu.Desc", "Game.Command.GmMenu.Usage", ["gm"], [PermEnum.Admin, PermEnum.Support])]
public class CommandGmMenu : ICommands
{
private static readonly Logger Logger = new("CommandManager");

[CommandDefault]
public async ValueTask ToggleGmMenu(CommandArg arg)
{
var option = arg.Args.FirstOrDefault()?.ToLowerInvariant() ?? "on";
var serverOption = ConfigManager.Config.ServerOption;
var player = arg.Target?.Player;
var message = option switch
{
"on" => await EnableGmMenu(serverOption, player),
"off" => await DisableGmMenu(serverOption, player),
_ => I18NManager.Translate("Game.Command.GmMenu.Usage")
};

Logger.Info(message);
await arg.SendMsg(message);
}

private static async ValueTask<string> EnableGmMenu(ServerOption serverOption, Game.Player.PlayerInstance? player)
{
serverOption.EnableGmMenu = true;
if (player != null) await player.SendScript("gm.notifylogin", new JsonObject
{
["IsDebug"] = ConfigManager.Config.ServerOption.EnableGmMenu
}.ToJsonString());
return I18NManager.Translate("Game.Command.GmMenu.Enabled");
}

private static async ValueTask<string> DisableGmMenu(ServerOption serverOption, Game.Player.PlayerInstance? player)
{
serverOption.EnableGmMenu = false;
if (player != null) await player.SendScript("gm.notifylogin", new JsonObject
{
["IsDebug"] = ConfigManager.Config.ServerOption.EnableGmMenu
}.ToJsonString());
return I18NManager.Translate("Game.Command.GmMenu.Disabled");
}
}
7 changes: 7 additions & 0 deletions GameServer/Game/Player/PlayerInstance.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,13 @@ public async ValueTask SendPacket(int cmdId, IMessage msg)
if (Connection?.IsOnline == true) await Connection.SendPacket(cmdId,msg);
}

public async Task SendScript(string api, string arg, NtfSyncPlayer extra = null!)
{
if (Connection?.IsOnline != true) return;
var rsp = new NtfCallScript { Api = api, Arg = arg, ExtraSync = extra };
await Connection.SendPacket(CmdIds.NtfScript, rsp);
}

#endregion

#region Actions
Expand Down
60 changes: 36 additions & 24 deletions Proxy/ProxyServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ public sealed class ProxyServer(
HttpClient httpClient,
Logger logger) : BackgroundService
{
private const string ListenAddress = "127.0.0.1";
private const string ServerHost = "127.0.0.1";
private static readonly string[] TargetDomains =
[
"amazingseasuncdn.com",
Expand Down Expand Up @@ -58,27 +56,37 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
return;
}

var address = IPAddress.Parse(ListenAddress);
_listener = new TcpListener(address, _options.Port);
_listener.Start();
logger.Info($"MikuSB proxy listening on {ListenAddress}:{_options.Port}");

try
for (var i = 0; i < 20; i++)
{
while (!stoppingToken.IsCancellationRequested)
try
{
var address = IPAddress.Parse(_options.BindAddress);
_listener = new TcpListener(address, _options.Port);
_listener.Start();
logger.Info($"MikuSB proxy listening on {_listener.LocalEndpoint}");

while (!stoppingToken.IsCancellationRequested)
{
var client = await _listener.AcceptTcpClientAsync(stoppingToken);
_ = Task.Run(() => HandleClientAsync(client, stoppingToken), stoppingToken);
}
}
catch (OperationCanceledException) when (stoppingToken.IsCancellationRequested)
{
}
catch (SocketException) when (stoppingToken.IsCancellationRequested)
{
// ignore stop
}
catch (SocketException ex)
{
logger.Info($"MikuSB proxy listening error {ex}");
_options.Port += Random.Shared.Next(1, 500); // try another port
await Task.Delay(100, stoppingToken);
}
catch (ObjectDisposedException) when (stoppingToken.IsCancellationRequested)
{
var client = await _listener.AcceptTcpClientAsync(stoppingToken);
_ = Task.Run(() => HandleClientAsync(client, stoppingToken), stoppingToken);
}
}
catch (OperationCanceledException) when (stoppingToken.IsCancellationRequested)
{
}
catch (SocketException) when (stoppingToken.IsCancellationRequested)
{
}
catch (ObjectDisposedException) when (stoppingToken.IsCancellationRequested)
{
}
}

Expand All @@ -94,7 +102,11 @@ private async Task HandleClientAsync(TcpClient client, CancellationToken cancell
{
using (client)
{
//logger.Debug($"Proxy New client: {client.Client.RemoteEndPoint}");
// TODO: pass client.Client.LocalEndPoint to SDK server
// let SDK server return IP/address for client to connect with
// api: /api/serverlist, /query_version, /query
var cliAddr = client.Client.RemoteEndPoint;
// logger.Debug($"Proxy New client: {cliAddr}");
try
{
await HandleClientCoreAsync(client, cancellationToken);
Expand All @@ -116,7 +128,7 @@ private async Task HandleClientAsync(TcpClient client, CancellationToken cancell
{
logger.Warn($"Proxy client failed {ex}");
}
logger.Info($"Proxy client close: {client.Client.RemoteEndPoint}");
// logger.Debug($"Proxy client close: {cliAddr}");
}
}

Expand Down Expand Up @@ -197,7 +209,7 @@ private async Task HandleRedirectedHttpLoopAsync(Stream tlsStream, string origin
private async Task ForwardToServerAsync(Stream clientStream, ProxyHttpRequest request, CancellationToken cancellationToken)
{
var pathAndQuery = request.GetPathAndQuery();
var uri = new Uri($"http://{ServerHost}:{_options.ServerHttpPort}{pathAndQuery}");
var uri = new Uri($"http://{_options.ServerHttpAddress}:{_options.ServerHttpPort}{pathAndQuery}");
if (ConfigManager.Config.HttpServer.EnableLog) logger.Info($"Redirect: {request.Method} {request.HostOverride ?? request.Host}{pathAndQuery} -> {uri}");
await SendHttpRequestAsync(clientStream, request, uri, true, cancellationToken);
}
Expand Down Expand Up @@ -227,7 +239,7 @@ private bool IsSelfReference(Uri uri)
return false;

return uri.Host is "127.0.0.1" or "localhost" or "::1"
|| uri.Host.Equals(ListenAddress, StringComparison.OrdinalIgnoreCase);
|| uri.Host.Equals(_options.BindAddress, StringComparison.OrdinalIgnoreCase);
}

private async Task SendHttpRequestAsync(Stream clientStream, ProxyHttpRequest request, Uri uri, bool addCors, CancellationToken cancellationToken)
Expand Down
6 changes: 3 additions & 3 deletions README_linux.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,20 @@

### setup steam launch options as following

`HTTP_PROXY="http://127.0.0.1:8888" HTTPS_PROXY="http://127.0.0.1:8888" ALL_PROXY="http://127.0.0.1:8888" %command%`
`ALL_PROXY="http://127.0.0.1:8888" %command%`

### start local server and keep it running

```
./MikuSB
```

### find root CA cert, and create ca bundle
### ~~find root CA cert, and create ca bundle~~ no neeeded

root CA cert, should in the path: `proxy-certs/MikuSB.Proxy.Root.pem`


### setup root CA for proton/wine
### ~~setup root CA for proton/wine~~ no neeeded

not sure, even I remove Proton PFX (Wine prefix) folder, without redo this step, still no cert issue.

Expand Down
Loading