M5: Windows client moderation UI; add C ABI getters for account list, user mute/deafen, channel topic
This commit is contained in:
@@ -215,6 +215,124 @@ public sealed class VoiceCatClient : IDisposable
|
||||
return (r, r == VcResult.Ok ? Marshaling.ToManaged(in native) : null);
|
||||
}
|
||||
|
||||
// ── M5: Moderation & admin ───────────────────────────────────────────────────────────
|
||||
public VcResult KickUser(uint userId, string? reason = null) =>
|
||||
NativeMethods.vc_kick_user(_handle.DangerousGetHandle(), userId, reason);
|
||||
|
||||
public VcResult BanUser(uint userId, string? reason = null, ulong expiresUnixMs = 0) =>
|
||||
NativeMethods.vc_ban_user(_handle.DangerousGetHandle(), userId, reason, expiresUnixMs);
|
||||
|
||||
public VcResult SetPermission(uint userId, PermissionsInfo perms)
|
||||
{
|
||||
var native = new VcPermissionsNative
|
||||
{
|
||||
CanCreateTempChannel = perms.CanCreateTempChannel ? 1 : 0,
|
||||
CanKick = perms.CanKick ? 1 : 0,
|
||||
CanBan = perms.CanBan ? 1 : 0,
|
||||
CanMoveUsers = perms.CanMoveUsers ? 1 : 0,
|
||||
CanAdminAccounts = perms.CanAdminAccounts ? 1 : 0,
|
||||
IsAdmin = perms.IsAdmin ? 1 : 0,
|
||||
};
|
||||
return NativeMethods.vc_set_permission(_handle.DangerousGetHandle(), userId, in native);
|
||||
}
|
||||
|
||||
public VcResult SetServerMute(uint userId, bool muted, bool deafened) =>
|
||||
NativeMethods.vc_set_server_mute(_handle.DangerousGetHandle(), userId,
|
||||
muted ? 1 : 0, deafened ? 1 : 0);
|
||||
|
||||
public VcResult MoveUser(uint userId, uint channelId) =>
|
||||
NativeMethods.vc_move_user(_handle.DangerousGetHandle(), userId, channelId);
|
||||
|
||||
public VcResult CreateChannel(ChannelEditInfo info)
|
||||
{
|
||||
var native = ToNativeChannelInfo(info);
|
||||
try
|
||||
{
|
||||
return NativeMethods.vc_create_channel(_handle.DangerousGetHandle(), in native);
|
||||
}
|
||||
finally
|
||||
{
|
||||
FreeChannelInfoStrings(native);
|
||||
}
|
||||
}
|
||||
|
||||
public VcResult EditChannel(ChannelEditInfo info)
|
||||
{
|
||||
var native = ToNativeChannelInfo(info);
|
||||
try
|
||||
{
|
||||
return NativeMethods.vc_edit_channel(_handle.DangerousGetHandle(), in native);
|
||||
}
|
||||
finally
|
||||
{
|
||||
FreeChannelInfoStrings(native);
|
||||
}
|
||||
}
|
||||
|
||||
public VcResult DeleteChannel(uint channelId) =>
|
||||
NativeMethods.vc_delete_channel(_handle.DangerousGetHandle(), channelId);
|
||||
|
||||
public VcResult CreateAccount(string username, string password) =>
|
||||
NativeMethods.vc_create_account(_handle.DangerousGetHandle(), username, password);
|
||||
|
||||
public VcResult ResetPassword(string username, string newPassword) =>
|
||||
NativeMethods.vc_reset_password(_handle.DangerousGetHandle(), username, newPassword);
|
||||
|
||||
public VcResult DeleteAccount(string username) =>
|
||||
NativeMethods.vc_delete_account(_handle.DangerousGetHandle(), username);
|
||||
|
||||
public VcResult RequestAccountList() =>
|
||||
NativeMethods.vc_list_accounts(_handle.DangerousGetHandle());
|
||||
|
||||
public List<AccountInfo> ListAccounts()
|
||||
{
|
||||
NativeMethods.vc_get_account_list(_handle.DangerousGetHandle(), out var native);
|
||||
return Marshaling.ToManaged(ref native);
|
||||
}
|
||||
|
||||
public PermissionsInfo GetPermissions()
|
||||
{
|
||||
NativeMethods.vc_get_permissions(_handle.DangerousGetHandle(), out var native);
|
||||
return Marshaling.ToManaged(in native);
|
||||
}
|
||||
|
||||
private static VcChannelInfoNative ToNativeChannelInfo(ChannelEditInfo info)
|
||||
{
|
||||
return new VcChannelInfoNative
|
||||
{
|
||||
Id = info.Id,
|
||||
ParentId = info.ParentId,
|
||||
Name = Marshal.StringToCoTaskMemUTF8(info.Name),
|
||||
Topic = Marshal.StringToCoTaskMemUTF8(info.Topic),
|
||||
PasswordProtected = info.PasswordProtected ? 1 : 0,
|
||||
Password = string.IsNullOrEmpty(info.Password)
|
||||
? 0
|
||||
: Marshal.StringToCoTaskMemUTF8(info.Password),
|
||||
MaxUsers = info.MaxUsers,
|
||||
SortOrder = info.SortOrder,
|
||||
Audio = new VcAudioConfigNative
|
||||
{
|
||||
Codec = info.Audio.Codec,
|
||||
Mode = info.Audio.Stereo ? 1u : 0u,
|
||||
SampleRate = info.Audio.SampleRate,
|
||||
BitrateBps = info.Audio.BitrateBps,
|
||||
FrameMs = info.Audio.FrameMs,
|
||||
Application = info.Audio.Application,
|
||||
Fec = info.Audio.Fec ? 1 : 0,
|
||||
ExpectedPacketLoss = info.Audio.ExpectedPacketLoss,
|
||||
Dtx = info.Audio.Dtx ? 1 : 0,
|
||||
Complexity = info.Audio.Complexity,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static void FreeChannelInfoStrings(VcChannelInfoNative native)
|
||||
{
|
||||
if (native.Name != 0) Marshal.FreeCoTaskMem(native.Name);
|
||||
if (native.Topic != 0) Marshal.FreeCoTaskMem(native.Topic);
|
||||
if (native.Password != 0) Marshal.FreeCoTaskMem(native.Password);
|
||||
}
|
||||
|
||||
// ── Text ─────────────────────────────────────────────────────────────────────────────
|
||||
public VcResult SendText(VcTextScope scope, uint targetId, string utf8) =>
|
||||
NativeMethods.vc_send_text(_handle.DangerousGetHandle(), scope, targetId, utf8);
|
||||
|
||||
Reference in New Issue
Block a user