using UnityEngine;
using System.Collections.Generic;
using System.Security.Policy;
using UnityEngine.Networking;
//Declaring the namespace all my scripts are found under
namespace Panzerwolf
{
//Declaring public struct.
//In this case ChatChannelId will only ever be referring
//to a value, not an instance of a class,
//thus I declare it as a struct.
[System.Serializable]
public struct ChatChannelId
{
//What the struct contains
public int value;
//Override methods, for adding functionality to the baseline methods
public override string ToString ()
{
return "Channel:" + value;
//This will return "ChatChannel:value" when called
//Very useful but not required anymore now I guess,
//I primarily used it for debugging
}
//The GetHashCode method is what a dictionary calls from an object
//to index it in
public override int GetHashCode()
{
//Typically two structs of type "ChatChannelId" would have the same HashCode.
//We override this by using their value as HashCodes,
//thus returning two unique HashCodes and separating them in a Dictionary
return (int)value;
}
//Generic method Equals
public override bool Equals(object obj)
{
//Checks if object to compare is actually a ChatChannelId,
//and if the object can be typecast as a ChatChannelId
return obj is ChatChannelId && this == (ChatChannelId)obj;
//Returns true only of both conditions match, else returns false
}
//Generic method CompareValue
//This is so the struct can be compared
//to other structs of the same type
//without returning true, by using the
//value of each struct
public static bool operator ==(ChatChannelId c1, ChatChannelId c2)
{
//Grabs the values for both structs and compares them
return c1.value == c2.value;
//Returns true if true(well, duh!)
}
//Generic method !CompareValue
//See above
public static bool operator !=(ChatChannelId c1, ChatChannelId c2)
{
return c1.value != c2.value;
}
}
//Declaring public struct
//See above
[System.Serializable]
public struct ChatPersonId
{
public int value;
public override string ToString ()
{
return "ChatPerson:" + value;
}
public override int GetHashCode()
{
return (int)value;
}
public override bool Equals (object obj)
{
return obj is ChatPersonId && this == (ChatPersonId)obj;
}
public static bool operator ==(ChatPersonId c1, ChatPersonId c2)
{
return c1.value == c2.value;
}
public static bool operator !=(ChatPersonId c1, ChatPersonId c2)
{
return c1.value != c2.value;
}
}
//Declaring public class
//This is a class..
//Why a class you ask?
//Because school is in session
[System.Serializable]
public class ChatPerson
{
//Declare static int so that it is a separate instance
//that carries the same value(including changes) across more than
//one instance of ChatPerson
static int nextPersonId = 2000;
//Name
public string personName;
//Struct ID
public ChatPersonId personId;
//A reference to the connection
public NetworkConnection connection;
//This will only be valid on server side
//ChatPerson constructor for client
public ChatPerson(string name, ChatPersonId id)
{
personName = name;
personId = id;
}
//ChatPerson constructor for server
public ChatPerson(string name, NetworkConnection conn)
{
personName = name;
personId.value = nextPersonId++;
connection = conn;
}
}
//Declaring public class
//See above
[System.Serializable]
public class ChatChannel
{
//Declare static
//See above
static int nextChannelId = 1000;
//Declaring public int(i use this one for message count)
//Note that it is not static so each channel
//has their own instance of the type "arbitraryCounter"
public int arbitraryCounter = 0;
//Name
public string channelName;
//Color of text in channel
public Color channelColor;
//Alias of the channel
public string channelAlias;
//Struct ID
public ChatChannelId channelId;
//**NOT USED**
public ChatPerson channelOwner;
//Declare public Dictionary.
//A dictionary is a list where you can input a key and get the associated value,
//or vise versa.
public Dictionary<ChatPersonId, ChatPerson> people = new Dictionary<ChatPersonId, ChatPerson> ();
//Calling "people[randomPersonId]" would return the corresponding ChatPerson VALUE
//associated with the KEY, while calling "people[randomChatPerson]" would return
//the ChatPersonId KEY associated with the VALUE.
//Declare public list
//A list is a place where you can store a reference of instances of the same type class.
public List<ChatPerson> peopleList = new List<ChatPerson>();
//Getting a reference to a spesific instance can be done with the Find and FindIndex method
//Use Find(delegate method) or FindIndex(int index)
//////////////////////////////////////////////////////////////////////////////////////////////
// Example: peopleList.Find(x => x.personName == personNameImLookingFor); //
// //
// Explanation: Find(x // this is the one you want to grab //
// => // where //
// x.value == value)// compares all references in the list to value //
// //
// This will return a reference to the first instance in the list //
// that matches your search method. //
//////////////////////////////////////////////////////////////////////////////////////////////
//See above
public List<TalkMessage> messages = new List<TalkMessage>();
//ChatChannel constructor for client
public ChatChannel (string name, ChatChannelId id, Color color, string alias)
{
channelName = name;
channelId = id;
channelColor = color;
}
//ChatChannel constructor for server
public ChatChannel(string name, Color color, string alias)
{
channelName = name;
channelColor = color;
channelAlias = alias;
channelId.value = nextChannelId++;
}
//**NOT USED**
//This is part of how I would allow a person to create a channel
// public bool CreateServer(ChatPerson person)
// {
// people [person.personId] = person;
// peopleList.Add (person);
// return true;
// }
//Declaring public bool
//Why a bool you ask?
//Because I like that the method returns true if it succeeds,
//and false if not.
public bool JoinServer(ChatPerson person)
{
//Checks if the people dictionary contains the person trying to join
if(people.ContainsKey(person.personId))
{
//Logs error to unity console or .exe console if dev mode is enabled
Debug.LogError ("Person already exists in channel");
return false;
}
//Create a new NetworkMessage to send
//Make it a type ChannelJoinResponseMessage
//This encrypts the NetworkMessage to this type,
//and requires that any receivers must decode it
//with a reader of the same type
var outMsg = new ChannelJoinResponseMessage ();
//Set message values
outMsg.channelName = channelName;
outMsg.channelAlias = channelAlias;
outMsg.channelId = channelId;
outMsg.channelColor = channelColor;
outMsg.personId = person.personId;
outMsg.personName = person.personName;
//For each person in the peoplelist,
foreach(var other in peopleList)
{
//send them the message containing the person that has joined
other.connection.Send (ChatMsg.ChannelJoin, outMsg);
}
//Add the person to the list
people [person.personId] = person;
peopleList.Add (person);
//For each person in the peopleList
foreach(var other in peopleList)
{
//Change the message to contain information about the
//other person in the channel peopleList
outMsg.personId = other.personId;
outMsg.personName = other.personName;
//send the person joining the channel a message containing
//information about the others in the channel
person.connection.Send (ChatMsg.ChannelJoin, outMsg);
}
//return true when successful
return true;
}
//See above
public bool LeaveServer(ChatPerson person)
{
//See above
if(!people.ContainsKey(person.personId))
{
//See above
Debug.LogError ("Person doesn't exist in channel");
return false;
}
//See above
var outMsg = new ChannelLeaveResponseMessage ();
outMsg.channelId = channelId;
outMsg.personId = person.personId;
//See above
foreach(var other in peopleList)
{
//Check if the connection is actually there
if (other.connection != null)
//Send the message containing information about who left
other.connection.Send (ChatMsg.ChannelLeave, outMsg);
else
//Remove the invalid connection's person from the list
peopleList.Remove (other);
}
Debug.LogError ("Removing person from channel..");
//Remove the person leaving the server from the dictionary and list
people.Remove (person.personId);
peopleList.Remove (person);
//See above
return true;
}
//See above
public bool ServerSay(ChatPerson person, string text)
{
//See above
if(!people.ContainsKey(person.personId))
{
//See above
Debug.LogError ("Channel does not contain player");
return false;
}
//In the process for implementing commands atm
//Disregard this
// if (text.Substring(0,1) == "/")
// Debug.LogError ("Was a command");
//See above
var outMsg = new TalkMessage ();
outMsg.personId = person.personId;
outMsg.channelId = channelId;
outMsg.text = text;
outMsg.count = arbitraryCounter;
//Add to the counter
arbitraryCounter++;
//See above
foreach(var other in peopleList)
{
other.connection.Send (ChatMsg.Talk, outMsg);
}
return true;
}
//Add person to channel
public void ClientAdd(ChatPerson person)
{
people [person.personId] = person;
peopleList.Add (person);
}
//Remove person from channel
public void ClientRemove(ChatPerson person)
{
peopleList.Remove (person);
}
}
}