|
Post by bulldogg on Apr 6, 2009 13:33:43 GMT
youd think id would of got the grasp of this by now lol
im using the entered base notification, how can i send a private chat event to the player who docked?
i can get their name and base from the notification but cant seem to find out how to go on from there
BD
|
|
|
Post by Eagle on Apr 6, 2009 14:20:56 GMT
The listener class has a protected field _serverInformation which is an instance of the ServerInformation class which in turn contains a property called OnlinePlayers with which you can enumerate all online players. Since its an IEnumerable collection, you can use LINQ queries to fetch the player you want. The following would allow you to fetch the online player with the name you seek: Player player = _serverInformation.OnlinePlayers.Single(p => p.Name == "name_searched"); Or in the form to use in the BaseEntered notification combined with sending private chat: PrivateChat.Fire(_serverInformation.OnlinePlayers.Single(p => p.Name == notification.PlayerName), "You entered a base..."); The most recent plug in example contains similar snippets that might prove usefull
|
|
|
Post by bulldogg on Apr 6, 2009 15:49:18 GMT
ah right ok
do you mind checking me this code?
public override void EnteredBase(EnteredBase notification) { XmlDocument doc = new XmlDocument(); doc.Load(Environment.GetFolderPath(Environment.SpecialFolder.Personal) + @"\FLAntiCheat\DockMessages.xml"); XmlElement root = doc.DocumentElement; XmlNodeList nodes = root.SelectNodes("//DockMessageConfig");
foreach (XmlNode node in nodes) { if (GetBaseName(notification.Base).ToString() == "Planet Manhattan (Li01_01_Base)") { PrivateChat.Fire(_serverInformation.OnlinePlayers.Single(p => p.Name == notification.PlayerName), "Welcome to Planet Manhattan"); } } / }
XML
<?xml version="1.0"?> <DockMessageConfig> <base> <nickname>Planet Manhattan (Li01_01_Base)</nickname> <message>Welcome to Planet Manhattan</message> </base> </DockMessageConfig>
|
|
|
Post by Eagle on Apr 6, 2009 17:46:13 GMT
You'd want to read the configuration file just once and be able to search in the collection base tags, assuming you intent to configure this for multiple systems. I'd recommend creating a new class to do this for you, you could call it Settings... infact you should look at the one used in the plug in example and define yours as a singleton (= 1 instance can be created at any time) as well. Have this class read the xml for you just once and store the nickname and message in a dictionary, with key being the nickname... actually the hash of the nickname as key! Few things you'll need to accomplish the above... 1st you'll need FLAC's configuration folder, which is a property of the ServerInformation class... no need for all this Environment.SpecialFolder stuff. Also, make sure you use Path.Combine (System.IO) to form valid filenames rather than concatenation like you are doing with the Environment class's properties, example: string configFile = Path.Combine(_serverInformation.ConfigurationFolder, "DockMessages.xml"); To calculate hashes from nicknames you can use the Hash class found in the EagleWare.Libraries.FreelancerTrivia namespace. Nicknames from bases as used in game ( not as found in FLAC's hashdb.ini!), could then match those provided in the EnteredBase notification's Base property, example: uint hashCode = Hash.Instance.Calculate("Li01_01_Base"); Once you have filled a dictionary with hash code & message pairs, you could write a method in your Settings or Configuration or whatever name you'll be using for your class which retrieves a message based on a has you put in or null if no such message exists. Example: public string GetDockMessage(uint hashCode) { return _dictionary.ContainsKey(hashCode)? _dictionary[hashCode]: null; } In the BaseEntered notification you could use that method as follows: string dockMessage = Setting.Instance.GetDockMessage(notification.Base); if(dockMessage == null) return; // nothing to send PrivateChat.Fire(player, dockMessage); Reading of an xml's nodes can indeed be done the way you're trying, you'll have to specify xpaths all the way up to nickname and message though and use the InnerText property to get the node contents. Alternatively you could setup a class structure which represents the xml's structure, something I've done in the Banners plug in... source of which is up for download so check it out
|
|
|
Post by bulldogg on Apr 12, 2009 18:11:04 GMT
REFRENCE CODE - pastebin.com/m357289dok this is something following onto the recent posts in this topic im running the code above and the notification enterbase returns this error 2009-04-12 19:06:20.484 [7] ERROR NotificationHandler`1 - Object reference not set to an instance of an object. System.NullReferenceException: Object reference not set to an instance of an object. at FlacPlugIn.DockMessage.NotificationHandler.GetDockMessage(UInt32 hashCode) at FlacPlugIn.DockMessage.NotificationHandler.EnteredBase(EnteredBase notification) at System.Action`1.Invoke(T obj) at FLAntiCheat.Notifications.NotificationHandler`1.Process() and the command listdockmessages also returns an error leading me to believe the dictionary hasnt been filled maybe? the config.ini is in this format BASE = MESSAGE Planet Manhattan (Li01_01_Base) = Welcome to Planet Manhattan eagle do you think you could help me with this, im kinda stuck as to why its not working, i know the code might not be that clean but oh well hehe, its only a first try at it, ill clean it up after i get it initially working BD
|
|
|
Post by Eagle on Apr 13, 2009 10:47:30 GMT
Start cleaning up before you try to debug, right now you're exposing what should be a private dictionary as a public field... make sure that can only be accessed from inside the class defining it, also make sure that the very 1st thing you do in a constructor is to initialize all your private fields such as the dictionary before performing any other tasks. Accessor methods you have to create for the dictionary should always check wether the requested key exists to prevent it from throwing exceptions. Right now, because the dictionary is public... you can access it from outside the class, which is very bad! You've also defined is as static, which is worse... never use static fields, those are a recipe for disaster and the reason you're getting null reference exceptions because there's not been any initialization. This because you've completely bypassed the singleton instance and went right for the public static field which does not belong to any instance... another reason to want to avoid static fields all together. Don't forget to replace those ugly string concatenations in forming paths, they're just wrong... also the means to obtain the configuration path is wrong... use the interface methods to retrieve the proper path instead so your plug in will work on all FLAC operated servers!
|
|
|
Post by bulldogg on Apr 13, 2009 14:28:17 GMT
using the flac config folder method seems to just return C:\FLAntiCheat which isnt right
|
|
|
Post by Eagle on Apr 14, 2009 8:10:20 GMT
Could be your FLAC copy points to a different folder depending on registry settings, if that folder is returned than that is the one used to find default config. Have you verified this on a live server environment?
|
|
|
Post by Eagle on Apr 15, 2009 18:00:58 GMT
Any more feedback on this?
|
|
|
Post by bulldogg on Apr 15, 2009 18:26:48 GMT
sorry not had the chance to do anythign with it, im away from the house at the moment
|
|