View Single Post
  #1  
Old 06-28-2012, 05:04 AM
podvoxx podvoxx is offline
Approved Member
 
Join Date: Feb 2010
Posts: 190
Default System of messages with localization

Hi all.
I created a messaging system that allows you to easily use them to send a group of players and translate the text. Transfer is carried out with the help of xml-files. The path to a text file you specify in the host-mission script.

The system works in all game modes, and on a dedicated server and is intended for designers of mission does not require much knowledge of c# and scripts.

Advantages:
-do not write message-code in every script, you just connect dll-file
-localization file is loaded only once
-easy to use
-works in all game modes (multiplayer in the game, dedicated server, single, campaign)
-you can translate the menu items
-you can use the numerical parameters in your messages

Installation.
Put the file smpMessage.dll in a game-folder:


Now, you must connect dll-file to your script for using message methods. See this code:
Connecting the system in the script:
Code:
//$reference "smpMessage.dll"
using System;
using maddox.game;
using maddox.game.world;
using smpmessage;

public class Mission : AMission
{
    // Path to localization xml-file if you want use translated text
    private static string localizationFilePath = Environment.GetFolderPath(Environment.SpecialFolder.Personal) + "\\1C SoftClub\\il-2 sturmovik cliffs of dover\\missions\\Single\\LocalizationExample\\localization.xml";

// Create dictionary for translate and send translated messages
    private static Translate Dictionary = Translate.UseConfigFile(localizationFilePath);

public override void OnBattleStarted()
    {
        base.OnBattleStarted();
        MissionNumberListener = -1;
        
        Dictionary.ToAll("SendMessageSection", "SendToChatToALLtranslate", "Chat");
        SendMessage.ToAll("Message to ALL - ENGLISH or ДРУГОЙ ЯЗЫК", "Chat");
    }
}
Localization file it's xml-file. It is loaded only once. This saves server resources, access to the hard drive occurs only once
Name of loc.file: any name
Format of loc. file:
Code:
<?xml version="1.0" encoding="utf-8"?>
<!-- Language dictionary-->
<SMP>	
	<LanguageSection name="SendMessageSection">		
		<Text key="SendToChatToALLtranslate">
			<en>Send To Chat To ALL translate ENGLISH</en>
			<ru>Send To Chat To ALL translate РУССКИЙ</ru>
		</Text>
		<Text key="SendToChatToPlayertranslate">
			<en>Send To Chat To Player translate ENGLISH</en>
			<ru>Send To Chat To Player translate РУССКИЙ</ru>
		</Text>
		<Text key="SendToChatToArmytranslate">
			<en>Send To Chat To Army translate ENGLISH</en>
			<ru>Send To Chat To Army translate РУССКИЙ</ru>
		</Text>
		<Text key="SendToScreenToALLtranslate">
			<en>Send To Screen To ALL translate ENGLISH</en>
			<ru>Send To Screen To ALL translate РУССКИЙ</ru>
		</Text>
		<Text key="SendToScreenToPlayertranslate">
			<en>Send To Screen To Player translate ENGLISH</en>
			<ru>Send To Screen To Player translate РУССКИЙ</ru>
		</Text>
		<Text key="SendToScreenToArmytranslate">
			<en>Send To Screen To Army translate ENGLISH</en>
			<ru>Send To Screen To Army translate РУССКИЙ</ru>
		</Text>		
		<Text key="SendToChatAndScreenToALLtranslate">
			<en>Send To Chat And Screen To ALL translate ENGLISH</en>
			<ru>Send To Chat And Screen To ALL translate РУССКИЙ</ru>
		</Text>
		<Text key="SendToChatAndScreenToPlayertranslate">
			<en>Send To Chat And Screen To Player translate ENGLISH</en>
			<ru>Send To Chat And Screen To Player translate РУССКИЙ</ru>
		</Text>
		<Text key="SendToChatAndScreenToArmytranslate">
			<en>Send To Chat And Screen To Army translate ENGLISH</en>
			<ru>Send To Chat And Screen To Army translate РУССКИЙ</ru>
		</Text>
		<Text key="GetTranslateText">
			<en>Get Translate Text ENGLISH</en>
			<ru>Get Translate Text РУССКИЙ</ru>
		</Text>
		<Text key="useParametersLabel">
			<en>Number1: {0}, Number2: {1}</en>
			<ru>Число 1: {0}, Число 2: {1}</ru>
		</Text>
	</LanguageSection>
	<LanguageSection name="Parameters">				
		<Text key="useParametersLabel">
			<en>Number1: {0}, Number2: {1}</en>
			<ru>Число 1: {0}, Число 2: {1}</ru>
		</Text>
	</LanguageSection>
</SMP>
If you do not translate message (only send) localization file and setting path to file are not needed. You must only adding dll-file unto your script

Code:
//$reference "smpMessage.dll"
using System;
using maddox.game;
using maddox.game.world;
using smpmessage;

public class Mission : AMission
{

public override void OnBattleStarted()
    {
        base.OnBattleStarted();
        MissionNumberListener = -1;        
        
        SendMessage.ToAll("Message to ALL - ENGLISH or ДРУГОЙ ЯЗЫК", "Chat");
    }
}
After create dictionary in host-mission you can add this dictionary in any submission script. To do this:
Code:
//$reference "smpMessage.dll"
using System;
using maddox.game;
using maddox.game.world;
using smpmessage;

public class Mission : AMission
{

    // Get dictionary for translate and send messages
    private static Translate Dictionary = Translate.GetInstance;

public override void OnBattleStarted()
    {
        base.OnBattleStarted();
        MissionNumberListener = -1;        
        
        Dictionary.ToAll("SendMessageSection", "SendToChatToALLtranslate", "Chat");
    }
}
You can use example mission in attache, put mission folder into "1C SoftClub\il-2 sturmovik cliffs of dover\missions\Single" in user-folder. Run mission and place enter aircraft. You see example messages

Example .cs-file:
Code:
//$reference "smpMessage.dll"
using System;
using maddox.game;
using maddox.game.world;
using smpmessage;
using System.Collections.Generic;

/* Available methods:
 * -- Translate and send message 
 * public static void ToAll(string section, string key, string target, params object[] args)
 * public static void ToArmy(string section, string key, int army, string target, params object[] args)
 * public static void ToPlayers(string section, string key, Player[] players, string target, params object[] args)
 * 
 * -- No translate, only send message
 * public static void ToAll(string message, string target, params object[] args)
 * public static void ToArmy(string message, int army, string target, params object[] args)
 * public static void ToPlayers(string message, Player[] players, string target, params object[] args)
 * public static void ToServer(string message, params object[] args)
 * 
 * -- Only translate, no send message
 * public string GetString(string section, string key, string language)
 *
 * Available languages in game:  en  ru  de  fr  es  cs  it  pl
*/

public class Mission : AMission
{
    // Path to localization xml-file, if you want to use localization on your script
    private static string localizationFilePath = Environment.GetFolderPath(Environment.SpecialFolder.Personal) + "\\1C SoftClub\\il-2 sturmovik cliffs of dover\\missions\\Single\\LocalizationExample\\localization.xml";

    // Create dictionary for translate and send messages
    private static Translate Dictionary = Translate.UseConfigFile(localizationFilePath);

    public override void OnBattleStarted()
    {
        base.OnBattleStarted();
        MissionNumberListener = -1;
    }

    public override void OnPlaceEnter(Player player, AiActor actor, int placeIndex)
    {
        base.OnPlaceEnter(player, actor, placeIndex);
        // TEST Messages
        // Translate and send message         
        Dictionary.ToAll("SendMessageSection", "SendToChatToALLtranslate", "Chat");
        Dictionary.ToPlayers("SendMessageSection", "SendToChatToPlayertranslate", new Player[] { player }, "Chat");
        Dictionary.ToArmy("SendMessageSection", "SendToChatToArmytranslate", 1, "Chat");

        Dictionary.ToAll("SendMessageSection", "SendToScreenToALLtranslate", "Screen");
        Dictionary.ToPlayers("SendMessageSection", "SendToScreenToPlayertranslate", new Player[] { player }, "Screen");
        Dictionary.ToArmy("SendMessageSection", "SendToScreenToArmytranslate", 1, "Screen");

        Dictionary.ToAll("SendMessageSection", "SendToChatAndScreenToALLtranslate", "ChatAndScreen");
        Dictionary.ToPlayers("SendMessageSection", "SendToChatAndScreenToPlayertranslate", new Player[] { player }, "ChatAndScreen");
        Dictionary.ToArmy("SendMessageSection", "SendToChatAndScreenToArmytranslate", 1, "ChatAndScreen");

        // No translate, only send message
        SendMessage.ToAll("Message to ALL - ENGLISH or ДРУГОЙ ЯЗЫК", "Chat");
        SendMessage.ToPlayers("Message to Players - ENGLISH or ДРУГОЙ ЯЗЫК", new Player[] { player }, "Chat");
        SendMessage.ToArmy("Message to Army - ENGLISH or ДРУГОЙ ЯЗЫК", 1, "Chat");

        SendMessage.ToAll("Message to ALL - ENGLISH or ДРУГОЙ ЯЗЫК", "Screen");
        SendMessage.ToPlayers("Message to Players - ENGLISH or ДРУГОЙ ЯЗЫК", new Player[] { player }, "Screen");
        SendMessage.ToArmy("Message to Army - ENGLISH or ДРУГОЙ ЯЗЫК", 1, "Screen");

        SendMessage.ToAll("Message to ALL - ENGLISH or ДРУГОЙ ЯЗЫК", "ChatAndScreen");
        SendMessage.ToPlayers("Message to Players - ENGLISH or ДРУГОЙ ЯЗЫК", new Player[] { player }, "ChatAndScreen");
        SendMessage.ToArmy("Message to Army - ENGLISH or ДРУГОЙ ЯЗЫК", 1, "ChatAndScreen");

        // Only translate, no send message
        //initTranslate.GetString("SendMessageSection", "GetTranslateText", "en");
        //initTranslate.GetString("SendMessageSection", "GetTranslateText", "ru");
        //initTranslate.GetString("SendMessageSection", "GetTranslateText", player.LanguageName());
        // Examples for using translated text:        
        SendMessage.ToAll(Dictionary.GetString("SendMessageSection", "GetTranslateText", "en"), "Chat");
        SendMessage.ToAll(Dictionary.GetString("SendMessageSection", "GetTranslateText", player.LanguageName()), "Chat");
        SendMessage.ToAll(Dictionary.GetString("SendMessageSection", "GetTranslateText", "de"), "Chat");

        // Using parameters in messages
        int number1 = 1000;
        int number2 = 500;
        SendMessage.ToAll("SendMessageSection", "============NO TRANSLATE LINE whith xml-file===========", "Chat");

        SendMessage.ToAll("Parameters", "useParametersLabel", "Chat", number1, number2);
        SendMessage.ToAll("Parameters", "useParametersLabel", "Screen", number1, number2);
        SendMessage.ToAll("Parameters", "useParametersLabel", "ChatAndScreen", number1, number2);

        SendMessage.ToAll("Number1 = {0}, Number2 = {1}", "Chat", number1, number2);
        SendMessage.ToAll("Number1 = {0}, Number2 = {1}", "Screen", number1, number2);
        SendMessage.ToAll("Number1 = {0}, Number2 = {1}", "ChatAndScreen", number1, number2);

        SendMessage.ToServer("This message only for server. No translate. {0}", "Only for chat!");

        SendMessage.ToAll("============NO TRANSLATE LINE whithout xml-file===========", "Chat");
    }
}
Code of dll-file:
Code:
using System;
using System.Collections.Generic;
using maddox.game;
using maddox.game.world;
using System.Xml;

namespace smpmessage
{
    // ====================================================
    // (based on Small_Bee and FG_Kodiak code)
    // ==================================================== 
    public sealed class Translate
    {
        #region Parameters
        private static readonly Lazy<Translate> Lazy = new Lazy<Translate>(() => new Translate());
        private static readonly Dictionary<string, Dictionary<string, Dictionary<string, string>>> _stringPool = new Dictionary<string, Dictionary<string, Dictionary<string, string>>>();
        static readonly IGamePlay GamePlay = Strategy.THIS.GamePlay;

        const string XmlLanguagenode = "SMP/LanguageSection";
        private const string DefaultLanguage = "en";
        public static string setupServerLanguage = "off";
        #endregion

        #region Read File
        public static Translate GetInstance
        {
            get { return Lazy.Value; }
        }


        private Translate()
        {
        }

        public static Translate UseConfigFile(string fileName)
        {
            if (_stringPool.Count == 0)
                LoadSettings(fileName);
            return Lazy.Value;
        }

        private static XmlDocument LoadXMLFile(string file)
        {
            // Load the xml-file in a xml-document
            XmlDocument xDoc = new XmlDocument();

            try
            {
                xDoc.Load(file);
            }
            catch (System.IO.FileNotFoundException)
            {
                throw new Exception("Xml-File " + file + " not found");
            }
            catch (Exception ex)
            {
                throw new Exception("Error loading " + file + ": " + ex.Message);
            }

            return xDoc;
        }

        private static void LoadSettings(string languageFile)
        {
            XmlDocument xDoc = LoadXMLFile(languageFile);

            var xmlNodeList = xDoc.SelectNodes(XmlLanguagenode);

            if (xmlNodeList != null)
                foreach (XmlNode sectionNode in xmlNodeList)
                {

                    var strs = new Dictionary<string, Dictionary<string, string>>();

                    foreach (XmlNode textNode in sectionNode.ChildNodes)
                    {

                        var texts = new Dictionary<string, string>();

                        foreach (XmlNode txt in textNode.ChildNodes)
                        {
                            texts.Add(txt.Name, txt.InnerText);
                        }

                        if (textNode.Attributes != null) strs.Add(textNode.Attributes["key"].Value, texts);
                    }

                    if (sectionNode.Attributes != null) _stringPool.Add(sectionNode.Attributes["name"].Value, strs);
                }

        }

        public string GetString(string section, string key, string language)
        {
            if (_stringPool.Count > 0)
            {
                Dictionary<string, Dictionary<string, string>> strs;

                if (_stringPool.TryGetValue(section, out strs))
                {
                    Dictionary<string, string> texts;

                    if (strs.TryGetValue(key, out texts))
                    {
                        string text;
                        if (setupServerLanguage == "off")
                        {
                            if (texts.TryGetValue(language, out text))
                                return text;
                            if (texts.TryGetValue(DefaultLanguage, out text))
                                return text;
                        }
                        else
                        {
                            if (texts.TryGetValue(setupServerLanguage, out text))
                                return text;
                            if (texts.TryGetValue(DefaultLanguage, out text))
                                return text;
                        }
                    }
                }
            }
            return key; // if nothing is found return a empty string -> modify if a error message is needed. 
        }
        
        public string GetString(string section, string key)
        {
            return GetString(section, key, DefaultLanguage);
        }
        
        #endregion

        #region Send Translate Message to List
        public void ToAll(string section, string key, string target, params object[] args)
        {
            switch (target)
            {
                case "ChatAndScreen":
                    {
                        Send(SendMessage.GetPlayerListChatAll(), section, key, "Chat", args);
                        Send(SendMessage.GetPlayerListScreenAll(), section, key, "Screen", args);
                    } break;
                case "Chat":
                    {
                        Send(SendMessage.GetPlayerListChatAll(), section, key, target, args);
                        break;
                    }
                case "Screen":
                    {
                        Send(SendMessage.GetPlayerListScreenAll(), section, key, target, args);
                    }
                    break;
            }
        }

        public void ToArmy(string section, string key, int army, string target, params object[] args)
        {
            Send(SendMessage.GetPlayerListArmy(army), section, key, target, args);
        }

        public void ToPlayers(string section, string key, Player[] players, string target, params object[] args)
        {
            Send(players, section, key, target, args);
        }
        #endregion

        #region Send
        private void Send(Player[] playerList, string section, string key, string target, params object[] args)
        {
            Dictionary<string, List<Player>> playerLanguageDict = new Dictionary<string, List<Player>>();

            foreach (Player player in playerList)
            {
                string languageName = player.LanguageName();
                if (!playerLanguageDict.ContainsKey(languageName))
                {
                    playerLanguageDict.Add(languageName, new List<Player>());
                }
                playerLanguageDict[languageName].Add(player);
            }

            if (playerList.Length > 0)
            {
                foreach (KeyValuePair<string, List<Player>> kvp in playerLanguageDict)
                {
                    SendMessage.Send(kvp.Value.ToArray(), GetString(section, key, kvp.Key.ToString()), target, args);
                }
            }
        }
        #endregion
    }

    public static class SendMessage
    {
        #region Parameters
        static readonly IGamePlay GamePlay = Strategy.THIS.GamePlay;
        public static string hudON = "off";   
        #endregion      

        #region Send Message to List
        public static void ToAll(string message, string target, params object[] args)
        {
            switch (target)
            {
                case "ChatAndScreen":
                    {
                        Send(GetPlayerListChatAll(), message, "Chat", args);
                        Send(GetPlayerListScreenAll(), message, "Screen", args);
                    } break;
                case "Chat":
                    {
                        Send(GetPlayerListChatAll(), message, target, args);                        
                        break;
                    }
                case "Screen": 
                    {
                        Send(GetPlayerListScreenAll(), message, target, args);                        
                    }
                    break;
            }
        }

        public static void ToArmy(string message, int army, string target, params object[] args)
        {
            Send(GetPlayerListArmy(army), message, target, args);
        }

        public static void ToPlayers(string message, Player[] players, string target, params object[] args)
        {
            Send(players, message, target, args);
        }

        public static void ToServer(string message, params object[] args)
        {
            Send(GetServer(), message, "Chat", args);
        }
        #endregion

        #region Send
        public static void Send(Player[] playerList, string message, string target, params object[] args)
        {            
            if (playerList.Length > 0)
            {
                switch (target)
                {
                    case "ChatAndScreen":
                    {
                        GamePlay.gpLogServer(playerList, message, args);
                        GamePlay.gpHUDLogCenter(playerList, message, args);
                    } break;
                    case "Chat":
                    {
                        GamePlay.gpLogServer(playerList, message, args);
                        break;
                    }
                    case "Screen":
                    {
                        GamePlay.gpHUDLogCenter(playerList, message, args);
                        if (hudON == "on")
                        {
                            GamePlay.gpLogServer(playerList, "[HUD]: " + message, args);
                        }
                        break;
                    }
                }
            }

        }
        #endregion

        #region GetPlayerList
        public static Player[] GetPlayerListScreenAll()
        {
            List<Player> players = new List<Player>();
            
            if (GamePlay.gpPlayer() != null)
                if (GamePlay.gpPlayer().Name().ToString() != "Server")
                {
                    players.Add(GamePlay.gpPlayer());
                }
            if (GamePlay.gpRemotePlayers() != null)
                players.AddRange(GamePlay.gpRemotePlayers());
            return players.ToArray();
        }

        public static Player[] GetPlayerListChatAll()
        {
            List<Player> players = new List<Player>();
            
            if (GamePlay.gpPlayer() != null)
                players.Add(GamePlay.gpPlayer());
            if (GamePlay.gpRemotePlayers() != null)
                players.AddRange(GamePlay.gpRemotePlayers());
            return players.ToArray();
        }

        public static Player[] GetPlayerListArmy(int army)
        {
            List<Player> players = new List<Player>();
            List<Player> acceptedPlayers = new List<Player>();
            if (GamePlay.gpPlayer() != null)
                players.Add(GamePlay.gpPlayer());
            if (GamePlay.gpRemotePlayers() != null)
                players.AddRange(GamePlay.gpRemotePlayers());

            if (players != null)
            {
                foreach (Player player in players)
                {
                    if (player.Army() == army) acceptedPlayers.Add(player);
                }               
            }
            return acceptedPlayers.ToArray();
        }

        public static Player[] GetServer()
        {
            List<Player> players = new List<Player>();
            
            if (GamePlay.gpPlayer() != null)
                players.Add(GamePlay.gpPlayer());
                /*
                if (GamePlay.gpPlayer().Name().ToString() == "Server")
                {
                    players.Add(GamePlay.gpPlayer());
                }
                */
            return players.ToArray();
        }
        #endregion
    }
}
Attached Files
File Type: zip dll file.zip (4.2 KB, 5 views)
File Type: zip LocalizationExample.zip (2.6 KB, 6 views)
File Type: zip VS2010project.zip (35.9 KB, 6 views)

Last edited by podvoxx; 08-17-2012 at 04:54 AM.
Reply With Quote