mirror of
https://git.alee14.me/shiftos-archive/ShiftOS_TheReturn.git
synced 2025-02-02 06:17:34 +00:00
Admin panel for chat frontend.
This commit is contained in:
parent
9f782550b5
commit
f5ef64e87d
9 changed files with 302 additions and 76 deletions
|
@ -67,15 +67,49 @@ namespace ShiftOS.Objects
|
|||
public string OnlineChat { get; set; }
|
||||
}
|
||||
|
||||
public class FriendlyNameAttribute : Attribute
|
||||
{
|
||||
public FriendlyNameAttribute(string name)
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
|
||||
public string Name { get; private set; }
|
||||
}
|
||||
|
||||
public class FriendlyDescriptionAttribute : Attribute
|
||||
{
|
||||
public FriendlyDescriptionAttribute(string desc)
|
||||
{
|
||||
Description = desc;
|
||||
}
|
||||
|
||||
public string Description { get; private set; }
|
||||
}
|
||||
|
||||
public class Channel
|
||||
{
|
||||
[FriendlyName("Chat name")]
|
||||
[FriendlyDescription("The human-readable name of your chat. This should be something small, possibly a one or two word description of your chat.")]
|
||||
public string Name { get; set; }
|
||||
|
||||
//Don't describe this one. We want it to be hidden from the admin panel's chat editor.
|
||||
public string ID { get; set; }
|
||||
|
||||
[FriendlyName("Chat topic")]
|
||||
[FriendlyDescription("A more in-depth version of your chat name. Describe what your chat's about in a sentence.")]
|
||||
public string Topic { get; set; }
|
||||
public int MaxUsers { get; set; } //0 for unlimited users (or the MUD maximum)
|
||||
public List<Save> Users = new List<Save>();
|
||||
|
||||
[FriendlyName("Is it a Discord relay?")]
|
||||
[FriendlyDescription("If checked, this channel will use a Discord bot to relay messages between ShiftOS and a chosen Discord channel. Useful if you'd like to integrate your MUD with the rest of your community.")]
|
||||
public bool IsDiscordProxy { get; set; }
|
||||
|
||||
[FriendlyName("Discord bot token")]
|
||||
[FriendlyDescription("If this is a discord relay chat, paste the token for your Discord bot here. Note: It MUST be a bot token, not a user token.")]
|
||||
public string DiscordBotToken { get; set; }
|
||||
|
||||
[FriendlyName("Discord channel ID")]
|
||||
[FriendlyDescription("If this channel is a Discord relay, paste the ID of the channel you'd like the bot to listen to here. You can get the channel ID by enabling Developer Mode in your Discord settings, then right-clicking your channel name and clicking 'Copy ID', then paste it here.")]
|
||||
public string DiscordChannelID { get; set; }
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
@ -122,6 +123,100 @@ namespace ShiftOS.Server.WebAdmin
|
|||
return false;
|
||||
}
|
||||
|
||||
public static string BuildFormFromObject(object obj)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.AppendLine("<form method='post' action=''><table class='table'>");
|
||||
foreach(var prop in obj.GetType().GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance))
|
||||
{
|
||||
string name = "";
|
||||
string description = "No description.";
|
||||
foreach(var attrib in prop.GetCustomAttributes(false))
|
||||
{
|
||||
if(attrib is FriendlyNameAttribute)
|
||||
{
|
||||
name = (attrib as FriendlyNameAttribute).Name;
|
||||
}
|
||||
if(attrib is FriendlyDescriptionAttribute)
|
||||
{
|
||||
description = (attrib as FriendlyDescriptionAttribute).Description;
|
||||
}
|
||||
}
|
||||
if (name != "")
|
||||
{
|
||||
sb.AppendLine("<tr>");
|
||||
|
||||
sb.AppendLine($@"<td width=""45%"">
|
||||
<p><strong>{name}</strong></p>
|
||||
<p>{description}</p>
|
||||
</td>
|
||||
<td>");
|
||||
if (prop.PropertyType == typeof(bool))
|
||||
{
|
||||
string isChecked = ((bool)prop.GetValue(obj) == true) ? "checked" : "";
|
||||
sb.AppendLine($"<input class='form-control' type='checkbox' name='{prop.Name}' {isChecked}/>");
|
||||
}
|
||||
else if (prop.PropertyType == typeof(string))
|
||||
{
|
||||
sb.AppendLine($"<input class='form-control' type='text' name='{prop.Name}' value='{prop.GetValue(obj)}'/>");
|
||||
}
|
||||
|
||||
sb.AppendLine("</td></tr>");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.AppendLine($"<input type='hidden' name='{prop.Name}' value='{prop.GetValue(obj)}'/>");
|
||||
}
|
||||
}
|
||||
sb.AppendLine("<tr><td></td><td><input class='btn btn-default' type='submit'/></td></tr>");
|
||||
sb.AppendLine("</table></form>");
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public static Channel GetChat(string id)
|
||||
{
|
||||
if (File.Exists("chats.json"))
|
||||
foreach (var channel in JsonConvert.DeserializeObject<List<Channel>>(File.ReadAllText("chats.json")))
|
||||
{
|
||||
if (channel.ID == id)
|
||||
return channel;
|
||||
}
|
||||
return new Channel();
|
||||
}
|
||||
|
||||
public static string GetAllChats()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.AppendLine("<table class=\"table\">");
|
||||
sb.AppendLine($@"<tr><td><strong>ID</strong></td>
|
||||
<td><strong>Name</strong></td>
|
||||
<td><strong>Topic</strong></td>
|
||||
<td><strong>Is Discord Relay</strong></td>
|
||||
<td><strong>Discord channel ID</strong></td>
|
||||
<td><strong>Discord Bot Token</strong></td>
|
||||
<td><strong>Actions</strong></td></tr>");
|
||||
if (File.Exists("chats.json"))
|
||||
{
|
||||
foreach(var chat in JsonConvert.DeserializeObject<List<Channel>>(File.ReadAllText("chats.json")))
|
||||
{
|
||||
sb.AppendLine($@"<tr>
|
||||
<td>{chat.ID}</td>
|
||||
<td>{chat.Name}</td>
|
||||
<td>{chat.Topic}</td>
|
||||
<td>{chat.IsDiscordProxy}</td>
|
||||
<td>{chat.DiscordChannelID}</td>
|
||||
<td>{chat.DiscordBotToken}</td>
|
||||
<td>
|
||||
<a href=""/mudadmin/editchat/{chat.ID}"" class=""btn btn-default""><span class=""glyphicon glyphicon-pencil""></span>Edit</a>
|
||||
<a href=""/mudadmin/deletechat/{chat.ID}"" class=""btn btn-default""><span class=""glyphicon glyphicon-delete""></span>Delete</a>
|
||||
</td>
|
||||
</tr>");
|
||||
}
|
||||
}
|
||||
sb.AppendLine("</table>");
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public static string GetCPWorth()
|
||||
{
|
||||
if (System.IO.Directory.Exists("saves"))
|
||||
|
@ -222,7 +317,7 @@ namespace ShiftOS.Server.WebAdmin
|
|||
|
||||
Get["/logout"] = parameters =>
|
||||
{
|
||||
return this.Logout("/");
|
||||
return this.Logout("~/");
|
||||
};
|
||||
|
||||
Post["/login"] = parameters =>
|
||||
|
@ -269,16 +364,111 @@ namespace ShiftOS.Server.WebAdmin
|
|||
this.RequiresClaims("Admin");
|
||||
Get["/"] = _ =>
|
||||
{
|
||||
return PageBuilder.Build("status", new Dictionary<string, string>{
|
||||
return statusBuilder();
|
||||
};
|
||||
Get["/status"] = _ =>
|
||||
{
|
||||
return statusBuilder();
|
||||
};
|
||||
Get["/chats"] = _ =>
|
||||
{
|
||||
return chatsListBuilder();
|
||||
};
|
||||
|
||||
Get["/createchat"] = _ =>
|
||||
{
|
||||
return PageBuilder.Build("editchat", new Dictionary<string, string>
|
||||
{
|
||||
{"{body}", Properties.Resources.ChatEditTemplate },
|
||||
{"{form}", SystemManager.BuildFormFromObject(new Channel()) }
|
||||
});
|
||||
};
|
||||
|
||||
Post["/createchat"] = parameters =>
|
||||
{
|
||||
var chat = this.Bind<Channel>();
|
||||
chat.ID = chat.Name.ToLower().Replace(" ", "_");
|
||||
List<Channel> chats = new List<Channel>();
|
||||
if (File.Exists("chats.json"))
|
||||
chats = JsonConvert.DeserializeObject<List<Channel>>(File.ReadAllText("chats.json"));
|
||||
|
||||
bool chatExists = false;
|
||||
|
||||
for (int i = 0; i < chats.Count; i++)
|
||||
{
|
||||
if (chats[i].ID == chat.ID)
|
||||
{
|
||||
chats[i] = chat;
|
||||
chatExists = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!chatExists)
|
||||
{
|
||||
chats.Add(chat);
|
||||
}
|
||||
|
||||
File.WriteAllText("chats.json", JsonConvert.SerializeObject(chats, Formatting.Indented));
|
||||
|
||||
return chatsListBuilder();
|
||||
};
|
||||
|
||||
Get["/editchat/{id}"] = parameters =>
|
||||
{
|
||||
return PageBuilder.Build("editchat", new Dictionary<string, string>
|
||||
{
|
||||
{"{body}", Properties.Resources.ChatEditTemplate },
|
||||
{"{form}", SystemManager.BuildFormFromObject(SystemManager.GetChat(parameters.id)) }
|
||||
});
|
||||
};
|
||||
|
||||
Post["/editchat/{id}"] = parameters =>
|
||||
{
|
||||
var chat = this.Bind<Channel>();
|
||||
chat.ID = chat.Name.ToLower().Replace(" ", "_");
|
||||
List<Channel> chats = new List<Channel>();
|
||||
if (File.Exists("chats.json"))
|
||||
chats = JsonConvert.DeserializeObject<List<Channel>>(File.ReadAllText("chats.json"));
|
||||
|
||||
bool chatExists = false;
|
||||
|
||||
for (int i = 0; i < chats.Count; i++)
|
||||
{
|
||||
if (chats[i].ID == chat.ID)
|
||||
{
|
||||
chats[i] = chat;
|
||||
chatExists = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!chatExists)
|
||||
{
|
||||
chats.Add(chat);
|
||||
}
|
||||
|
||||
File.WriteAllText("chats.json", JsonConvert.SerializeObject(chats, Formatting.Indented));
|
||||
return chatsListBuilder();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
private string statusBuilder()
|
||||
{
|
||||
return PageBuilder.Build("status", new Dictionary<string, string>{
|
||||
{ "{cp_worth}", SystemManager.GetCPWorth() },
|
||||
{ "{user_count}", SystemManager.GetUserCount() },
|
||||
{ "{system_time}", DateTime.Now.ToString() },
|
||||
});
|
||||
};
|
||||
Get["/status"] = _ =>
|
||||
|
||||
}
|
||||
|
||||
private string chatsListBuilder()
|
||||
{
|
||||
return PageBuilder.Build("bla", new Dictionary<string, string>
|
||||
{
|
||||
return PageBuilder.Build("status");
|
||||
};
|
||||
{ "{body}", Properties.Resources.ChatListView },
|
||||
{ "{chat_table}", SystemManager.GetAllChats() }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -60,6 +60,34 @@ namespace ShiftOS.Server.WebAdmin.Properties {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to <h3>Create/edit chat</h3>
|
||||
///
|
||||
///<p>Please fill out the details below for your channel list to be modified.</p>
|
||||
///
|
||||
///{form}.
|
||||
/// </summary>
|
||||
internal static string ChatEditTemplate {
|
||||
get {
|
||||
return ResourceManager.GetString("ChatEditTemplate", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to <h3>Chats</h3>
|
||||
///
|
||||
///<p>On this page you can find a list of all chats in the system. Chats are a part of the multi-user domain that allows online players to talk to eachother in the 'MUD Chat' application.</p>
|
||||
///
|
||||
///<p>If you have a Discord server for your multi-user domain, you can also designate a ShiftOS chat to listen on a specific channel on your server. You will need to create a Discord Bot Token and specify the ID of the channel you want tolisten to.</p>
|
||||
///
|
||||
///<p>Once the chat is set up, you should see a bot [rest of string was truncated]";.
|
||||
/// </summary>
|
||||
internal static string ChatListView {
|
||||
get {
|
||||
return ResourceManager.GetString("ChatListView", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to <html>
|
||||
/// <head>
|
||||
|
|
|
@ -118,6 +118,12 @@
|
|||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="ChatEditTemplate" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\ChatEditTemplate.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
|
||||
</data>
|
||||
<data name="ChatListView" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\ChatListView.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
|
||||
</data>
|
||||
<data name="HtmlTemplate" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\HtmlTemplate.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
|
||||
</data>
|
||||
|
|
5
ShiftOS.Server.WebAdmin/Resources/ChatEditTemplate.txt
Normal file
5
ShiftOS.Server.WebAdmin/Resources/ChatEditTemplate.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
<h3>Create/edit chat</h3>
|
||||
|
||||
<p>Please fill out the details below for your channel list to be modified.</p>
|
||||
|
||||
{form}
|
11
ShiftOS.Server.WebAdmin/Resources/ChatListView.txt
Normal file
11
ShiftOS.Server.WebAdmin/Resources/ChatListView.txt
Normal file
|
@ -0,0 +1,11 @@
|
|||
<h3>Chats</h3>
|
||||
|
||||
<p>On this page you can find a list of all chats in the system. Chats are a part of the multi-user domain that allows online players to talk to eachother in the 'MUD Chat' application.</p>
|
||||
|
||||
<p>If you have a Discord server for your multi-user domain, you can also designate a ShiftOS chat to listen on a specific channel on your server. You will need to create a Discord Bot Token and specify the ID of the channel you want tolisten to.</p>
|
||||
|
||||
<p>Once the chat is set up, you should see a bot join your Discord server. Once it does, any messages received by the server in that channel will be relayed into ShiftOS, and any messages received by the MUD in the ShiftOS channel will be relayed to Discord.</p>
|
||||
|
||||
<a href="/mudadmin/createchat" class="btn btn-default"><span class="glyphicon glyphicon-plus"></span> Create chat</a>
|
||||
|
||||
{chat_table}
|
|
@ -15,25 +15,28 @@
|
|||
</div>
|
||||
<ul class="nav navbar-nav">
|
||||
<li>
|
||||
<a href="/webadmin/status">System status</a>
|
||||
<a href="/mudadmin/status">System status</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/webadmin/saves">Test subjects</a>
|
||||
<a href="/mudadmin/saves">Test subjects</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/webadmin/shiftnet">Shiftnet</a>
|
||||
<a href="/mudadmin/shiftnet">Shiftnet</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/webadmin/scripts">Scripts</a>
|
||||
<a href="/mudadmin/scripts">Scripts</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/webadmin/legions">Legions</a>
|
||||
<a href="/mudadmin/legions">Legions</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/mudadmin/chats">Chats</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/mudadmin/shops">Shops</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/webadmin/shops">Shops</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/webadmin/help">Help</a>
|
||||
<a href="/mudadmin/help">Help</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
|
|
|
@ -103,6 +103,12 @@
|
|||
<ItemGroup>
|
||||
<None Include="Resources\Status.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Resources\ChatListView.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Resources\ChatEditTemplate.txt" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
|
|
|
@ -79,36 +79,6 @@ namespace ShiftOS.Server
|
|||
/// </summary>
|
||||
public static event StringEventHandler ServerStarted;
|
||||
|
||||
/// <summary>
|
||||
/// Saves the chats.
|
||||
/// </summary>
|
||||
/// <returns>The chats.</returns>
|
||||
public static void SaveChats()
|
||||
{
|
||||
List<Channel> saved = new List<Channel>();
|
||||
foreach(var chat in chats)
|
||||
{
|
||||
saved.Add(new Channel
|
||||
{
|
||||
ID = chat.ID,
|
||||
Name = chat.Name,
|
||||
MaxUsers = chat.MaxUsers,
|
||||
Topic = chat.Topic,
|
||||
Users = new List<Save>()
|
||||
});
|
||||
}
|
||||
File.WriteAllText("chats.json", JsonConvert.SerializeObject(saved));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads the chats.
|
||||
/// </summary>
|
||||
/// <returns>The chats.</returns>
|
||||
public static void LoadChats()
|
||||
{
|
||||
chats = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Channel>>(File.ReadAllText("chats.json"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The entry point of the program, where the program control starts and ends.
|
||||
/// </summary>
|
||||
|
@ -121,15 +91,6 @@ namespace ShiftOS.Server
|
|||
Directory.CreateDirectory("saves");
|
||||
}
|
||||
|
||||
if(!File.Exists("chats.json"))
|
||||
{
|
||||
SaveChats();
|
||||
}
|
||||
else
|
||||
{
|
||||
LoadChats();
|
||||
}
|
||||
|
||||
if(!Directory.Exists("scripts"))
|
||||
{
|
||||
Console.WriteLine("Creating scripts directory...");
|
||||
|
@ -202,28 +163,10 @@ namespace ShiftOS.Server
|
|||
Console.WriteLine("Server stopping.");
|
||||
|
||||
};
|
||||
ChatBackend.StartDiscordBots();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Users the in chat.
|
||||
/// </summary>
|
||||
/// <returns>The in chat.</returns>
|
||||
/// <param name="chan">Chan.</param>
|
||||
/// <param name="user">User.</param>
|
||||
public static bool UserInChat(Channel chan, Save user)
|
||||
{
|
||||
foreach(var usr in chan.Users)
|
||||
{
|
||||
if(usr.Username == user.Username)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static string ReadEncFile(string fPath)
|
||||
public static string ReadEncFile(string fPath)
|
||||
{
|
||||
return Encryption.Decrypt(File.ReadAllText(fPath));
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue