using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;
using UnityEngine.Networking;
//Declaring the namespace all my scripts are found under
namespace Panzerwolf
{
//Using everything from the previous scripts,
//this one should be understandable without a significant amount of commenting.
//You could try commenting it out yourself to test your understanding.
//If you see functions here that aren't being called through code,
//they are being called through UI elements in the program
public class ChatServer : MonoBehaviour
{
NetworkServerSimple server = null;
//Unity stuff
[SerializeField]GameObject StopServer;
[SerializeField]GameObject CreateServer;
[SerializeField]GameObject channelView;
[SerializeField]GameObject channelPrefab;
[SerializeField]InputField channelInput;
//Returns an int
[SerializeField]Dropdown dropdownClassPicker;
public int chatServerPort = 9999;
public int maxConnections = 48;
//This is the value I use to classify channels as Global, Local, Party or Guild
public int channelClassification = 0;
public Dictionary<ChatChannelId, ChatChannel> channels = new Dictionary<ChatChannelId, ChatChannel>();
Dictionary<string, ChatChannel> channelsByName = new Dictionary<string, ChatChannel>();
// Dictionary<string, ChatChannel> channelsByAlias = new Dictionary<string, ChatChannel>();
public Dictionary<ChatPersonId, ChatPerson> people = new Dictionary<ChatPersonId, ChatPerson>();
public Dictionary<int, ChatPerson> logins = new Dictionary<int, ChatPerson>();
//Setup the server
public void Setup()
{
if(server == null)
{
server = new NetworkServerSimple();
//Setting up the handlers
server.RegisterHandler(MsgType.Connect, OnConnect);
server.RegisterHandler(MsgType.Disconnect, OnDisconnect);
server.RegisterHandler(ChatMsg.ChannelJoin, OnChannelJoin);
server.RegisterHandler(ChatMsg.ChannelLeave, OnChannelLeave);
// server.RegisterHandler(ChatMsg.ChannelCreate, OnChannelCreate);
server.RegisterHandler(ChatMsg.Talk, OnTalk);
server.RegisterHandler(ChatMsg.Login, OnLogin);
// server.RegisterHandler(ChatMsg.Logoff, OnLogoff);
server.Listen(chatServerPort);
Debug.Log ("Server up!");
// CreateChannel ("Global");
// CreateChannel ("Local");
// CreateChannel ("Party");
//Unity UI stuff
CreateServer.SetActive (false);
StopServer.SetActive (true);
}
}
public void Stop()
{
//Unity UI stuff
for(int i = 0; i < channelView.transform.childCount; i++)
{
Destroy (channelView.transform.GetChild (i).gameObject);
}
CreateServer.SetActive (true);
StopServer.SetActive (false);
//Clear the channel lists
channels.Clear ();
channelsByName.Clear ();
//Stop the server
server.Stop ();
//Reset the server to null
server = null;
}
//This gets called once every frame
void Update ()
{
if (server != null)
{
//Send incoming data and outgoing data
server.Update ();
}
}
//Method to get reference to channel using name
#region Utility
ChatChannel FindChannel(string name)
{
if (channelsByName.ContainsKey(name))
{
return channelsByName[name];
}
return null;
}
//Method to get reference to channel using id
ChatChannel FindChannel(ChatChannelId id)
{
if (channels.ContainsKey(id))
{
return channels[id];
}
return null;
}
//Method to get reference to person using id
ChatPerson FindPerson(ChatPersonId id)
{
if (people.ContainsKey(id))
{
return people[id];
}
return null;
}
#endregion
//Known
void OnConnect(NetworkMessage netMsg)
{
Debug.Log("Chat client connect");
}
//Known
void OnDisconnect(NetworkMessage netMsg)
{
//When someone disconnects, remove their connection from the logins list
logins.Remove (netMsg.conn.connectionId);
Debug.Log("Chat client disconnect");
}
//Known
void OnLogin(NetworkMessage netMsg)
{
var msg = netMsg.ReadMessage<LoginMessage> ();
if(logins.ContainsKey(netMsg.conn.connectionId))
{
Debug.LogError ("Client already logged in");
return;
}
var person = new ChatPerson (msg.personName, netMsg.conn);
//Add person to logins list at index connectionId
logins [netMsg.conn.connectionId] = person;
//Add person to people list
people [person.personId] = person;
Debug.Log("Login: " + person.personName + " " + person.personId);
//Send LoginResponse to the client that is requesting a logon
var response = new LoginResponseMessage();
response.personName = msg.personName;
response.personId = person.personId;
netMsg.conn.Send(ChatMsg.Login, response);
}
void OnChannelJoin(NetworkMessage netMsg)
{
if (!logins.ContainsKey(netMsg.conn.connectionId))
{
Debug.LogError("Not logged in");
return;
}
var msg = netMsg.ReadMessage<ChannelJoinRequestMessage>();
Debug.Log ("Server OnChannelJoin called");
var channel = FindChannel(msg.name);
if (channel == null)
{
Debug.LogError("channel not found " + msg.name);
var outMsg = new ChannelJoinFailedMessage ();
netMsg.conn.Send (ChatMsg.ChannelFailed, outMsg);
return;
}
var person = FindPerson(msg.personId);
if (person == null)
{
Debug.LogError("person not found " + msg.personId);
return;
}
channel.JoinServer(person);
Debug.Log("Join: " + channel.channelName + " " + person.personId);
}
void OnChannelLeave(NetworkMessage netMsg)
{
if(!logins.ContainsKey(netMsg.conn.connectionId))
{
Debug.LogError ("Can't leave channel: not logged in");
return;
}
var msg = netMsg.ReadMessage<ChannelLeaveRequestMessage> ();
var channel = FindChannel (msg.channelId);
if(channel == null)
{
Debug.LogError ("Channel not found");
return;
}
var person = FindPerson (msg.personId);
if(person == null)
{
Debug.LogError ("Person not found");
return;
}
channel.LeaveServer (person);
Debug.Log ("Left channel");
}
void OnTalk(NetworkMessage netMsg)
{
if (!logins.ContainsKey(netMsg.conn.connectionId))
{
Debug.LogError("OnTalk Not logged in");
return;
}
var msg = netMsg.ReadMessage<TalkMessage>();
var channel = FindChannel(msg.channelId);
if (channel == null)
{
Debug.LogError("OnTalk channel not found " + msg.channelId);
return;
}
var person = FindPerson(msg.personId);
if (person == null)
{
Debug.LogError("OnTalk person not found " + msg.personId);
return;
}
channel.ServerSay(person, msg.text);
Debug.Log("Talk: " + msg.text + " " + person.personId);
}
public void ButtonCreateChannel()
{
string Name = channelInput.text;
string Alias = "";
Color color = new Color ();
if(channelClassification == 0)
{
foreach(var ch in channels)
{
if (ch.Value.channelAlias == "Global")
{
Debug.LogError ("Can only have one Global aliased channel");
return;
}
}
color = Color.white;
Alias = "Global";
}
else if(channelClassification == 1)
{
color = Color.yellow;
Alias = "Local";
}
else if(channelClassification == 2)
{
color = Color.cyan;
Alias = "Party";
}
else if(channelClassification == 3)
{
color = Color.green;
Alias = "Guild";
}
var newChannel = CreateChannel (Name, color, Alias);
if (newChannel == null)
{
return;
}
GameObject channel = Instantiate (channelPrefab);
channel.transform.SetParent (channelView.transform);
channel.transform.GetChild (0).GetComponent<Button> ().onClick.AddListener (() => RemoveChannel (Name, newChannel.channelId));
channel.transform.GetChild (1).GetComponent<Text> ().text = channelInput.text;
channel.transform.GetChild (1).GetComponent<Text> ().color = color;
channel.name = "Channel: " + Name;
channelInput.text = string.Empty;
}
public void ChangeColor()
{
channelClassification = dropdownClassPicker.value;
Debug.Log (channelClassification);
}
public void RemoveChannel(string name, ChatChannelId channelid )
{
Debug.Log ("Removechannel called!");
channels [channelid].people.Clear ();
channels [channelid].peopleList.Clear ();
channels.Remove (channelid);
channelsByName.Remove (name);
Destroy(GameObject.Find ("Channel: " + name));
}
ChatChannel CreateChannel(string name, Color color, string alias)
{
foreach (var ch in channels.Values)
{
if (ch.channelName == name)
{
Debug.Log("Create: already exists " + name);
return null;
}
}
var channel = new ChatChannel(name, color, alias);
channels[channel.channelId] = channel;
channelsByName[channel.channelName] = channel;
// channel.CreateServer();
Debug.Log("Created channel " + channel.channelName);
return channel;
// var response = new ChannelCreateResponseMessage();
// response.channelName = channel.channelName;
// response.channelId = channel.channelId;
//
// netMsg.conn.Send(ChatMsg.ChannelCreate, response);
}
}
}