View Full Version : How add user dll
podvoxx
05-21-2012, 10:10 AM
I need to transfer the same parts of the code, which often use in dll-file in the game. For example the code localization(to send messages) and use of global variables in the hostmission and submission scripts. One file will be used in different scripts.
For example code of my dll-file:
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using maddox.game;
using maddox.game.world;
using maddox.GP;
using part;
namespace locfiledll
{
public class localization : AMission
{
public static int locText(int number1, int number2)
{
int result = number1 + number2;
return result;
}
}
}
My mission script:
//$reference "P11_folder\P11_localization.dll"
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using maddox.game;
using maddox.game.world;
using maddox.GP;
using locfiledll;
public class Mission : localization
{
public override void OnBattleStarted()
{
base.OnBattleStarted();
MissionNumberListener = -1;
int xxx = localization.locText(1, 2);
//SendMessageToAll("Расчет из DLL = " + xxx.ToString(), "Chat");
//LOAD MAIN MISSION MAP OBJEKTS
//GamePlay.gpPostMissionLoad("missions\\SMP\\Friday on my mind\\submissions\\Map AAA\\Map AAA.mis");
}
In this code I have error on game(Exception). How I can use method localization.locText()?
And can I use this code:
[/CODE]
My mission script:
//$reference "P11_folder\P11_localization.dll"
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using maddox.game;
using maddox.game.world;
using maddox.GP;
using locfiledll;
public class Mission : AMission
{
public override void OnBattleStarted()
{
base.OnBattleStarted();
MissionNumberListener = -1;
int xxx = localization.locText(1, 2);
//SendMessageToAll("Расчет из DLL = " + xxx.ToString(), "Chat");
//LOAD MAIN MISSION MAP OBJEKTS
//GamePlay.gpPostMissionLoad("missions\\SMP\\Friday on my mind\\submissions\\Map AAA\\Map AAA.mis");
}
Maybe someone has a ready example of a simple dll?
FG28_Kodiak
05-21-2012, 10:41 AM
For example i use this in my dll:
using System.Collections.Generic;
using System.Globalization;
using maddox.game;
using maddox.game.world;
namespace COD
{
public static class Message
{
static readonly IGamePlay GamePlay = Strategy.THIS.GamePlay;
public static void ToChatbar(string msg, params object[] args)
{
GamePlay.gpLogServer(null, msg, args);
}
public static void ToChatbar(Player player, string msg, params object[] args)
{
if (player != null)
GamePlay.gpLogServer(new[] { player }, msg, args);
}
public static void ToChatbar(int army, string msg, params object[] args)
{
var consignees = new List<Player>();
if (GamePlay.gpPlayer() != null)
consignees.Add(GamePlay.gpPlayer());
if (GamePlay.gpRemotePlayers() != null)
consignees.AddRange(GamePlay.gpRemotePlayers());
if (army == -1)
GamePlay.gpLogServer(null, msg, args);
else if (consignees.Exists(item => item.Army() == army))
GamePlay.gpLogServer(consignees.FindAll(item => item.Army() == army).ToArray(), msg, args);
}
public static void ToScreen(string msg, params object[] args)
{
GamePlay.gpHUDLogCenter(null, msg, args);
}
public static void ToScreen(Player player, string msg, params object[] args)
{
if (player != null)
GamePlay.gpHUDLogCenter(new[] { player }, msg, args);
}
public static void ToScreen(int army, string msg, params object[] args)
{
var consignees = new List<Player>();
if (GamePlay.gpPlayer() != null)
consignees.Add(GamePlay.gpPlayer());
if (GamePlay.gpRemotePlayers() != null)
consignees.AddRange(GamePlay.gpRemotePlayers());
if (army == -1)
GamePlay.gpHUDLogCenter(null, msg, args);
else if (consignees.Exists(item => item.Army() == army))
GamePlay.gpHUDLogCenter(consignees.FindAll(item => item.Army() == army).ToArray(), msg, args);
}
public static void ToScreenCountDown(string message, string endMessage, int seconds)
{
string tmpMessage = message + " ";
int count = 0;
while (count < seconds)
{
Strategy.THIS.Timeout(count++, () =>
{
ToScreen(tmpMessage + seconds--.ToString(CultureInfo.InvariantCulture));
});
}
Strategy.THIS.Timeout(count, () => ToScreen(endMessage));
}
public static void ToScreenCountDown(Player player, string message, string endMessage, int seconds)
{
string tmpMessage = message + " ";
int count = 0;
while (count < seconds)
{
Strategy.THIS.Timeout(count++, () =>
{
ToScreen(player, tmpMessage + seconds--.ToString(CultureInfo.InvariantCulture));
});
}
Strategy.THIS.Timeout(count, () => ToScreen(player, endMessage));
}
public static void ToScreenCountDown(int army, string message, string endMessage, int seconds)
{
string tmpMessage = message + " ";
int count = 0;
while (count < seconds)
{
Strategy.THIS.Timeout(count++, () =>
{
ToScreen(army, tmpMessage + seconds--.ToString(CultureInfo.InvariantCulture));
});
}
Strategy.THIS.Timeout(count, () => ToScreen(army, endMessage));
}
}
}
In the script file i use
//$reference parts/core/COD.dll //reference to my dll (Assembly)
using System;
using maddox.game;
using maddox.game.world;
using COD; //My namespace
public class Mission : AMission
{
public override void OnPlaceEnter(Player player, AiActor actor, int placeIndex)
{
base.OnPlaceEnter(player, actor, placeIndex);
Message.ToChatbar(player, "Welcome {0}", player);
}
}
podvoxx
05-21-2012, 12:00 PM
For example i use this in my dll:
Thank you very much! I will try your version later.
podvoxx
05-21-2012, 07:09 PM
Not work :(, I have this error whith your code:
[22:50:10] =================================================
[22:50:10] System.IO.FileNotFoundException: Could not load file or assembly 'SMPlocalization, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. Не удается найти указанный файл.
[22:50:10] File name: 'SMPlocalization, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'
[22:50:10]
[22:50:10] Server stack trace:
[22:50:10] at Mission.OnTickGame()
[22:50:10] at maddox.game.ABattle.OnTickGame()
[22:50:10] at maddox.game.world.Strategy.OnTickGame()
[22:50:10] at System.Runtime.Remoting.Messaging.StackBuilderSink ._PrivateProcessMessage(IntPtr md, Object[] args, Object server, Int32 methodPtr, Boolean fExecuteInContext, Object[]& outArgs)
[22:50:10] at System.Runtime.Remoting.Messaging.StackBuilderSink .SyncProcessMessage(IMessage msg, Int32 methodPtr, Boolean fExecuteInContext)
[22:50:10]
[22:50:10] Exception rethrown at [0]:
[22:50:10] at System.Runtime.Remoting.Proxies.RealProxy.HandleRe turnMessage(IMessage reqMsg, IMessage retMsg)
[22:50:10] at System.Runtime.Remoting.Proxies.RealProxy.PrivateI nvoke(MessageData& msgData, Int32 type)
[22:50:10] at maddox.game.IBattle.OnTickGame()
[22:50:10] at maddox.game.GameDef.tickGame()
[22:50:10] at Rnn9R0HNW1FFeT2aIDs.ltiVH2HK9YyK7SdiCrk.8IDxVdt1dP yeHPkw7Ndf(Object )
[22:50:10] at Rnn9R0HNW1FFeT2aIDs.ltiVH2HK9YyK7SdiCrk.NaqwoOS5Jo c()
[22:50:10] at JHVeKKyORf15WCVE1pL.eE20r2yPeQB95WctiCJ.ZRMSPQBwmi C(Boolean , Boolean )
[22:50:10]
[22:50:10] WRN: Assembly binding logging is turned OFF.
[22:50:10] To enable assembly bind failure logging, set the registry value [HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) to 1.
[22:50:10] Note: There is some performance penalty associated with assembly bind failure logging.
[22:50:10] To turn this feature off, remove the registry value [HKLM\Software\Microsoft\Fusion!EnableLog].
[22:50:10]
[22:50:10] =================================================
FG28_Kodiak
05-21-2012, 09:21 PM
Where do you store the file?
For multiplayer it must (should maybe there is another location too) be in "..\Steam\SteamApps\common\il-2 sturmovik cliffs of dover\parts\core" at the moment, until we can create Addins and specify the path of the User Dlls in the xml-file.
Smokeynz
05-21-2012, 11:12 PM
I've been wondering about this, or how to modulise methods into individually run code when required.
What sort of restrictions is there at present for dll's?
Actually how do you turn a cs script into a dll?
Kodiak, I see also you run multible occurances of a public static void ToChatBar
I thought this conflicted? How does it know which one to use?
FG28_Kodiak
05-22-2012, 04:33 AM
What sort of restrictions is there at present for dll's?
Normally none.
Actually how do you turn a cs script into a dll?
In Visual select Class Library, after entering code, generate the project. After that (without error) you will find the dll in "..\bin\Debug" (or ..\bin\Release depens on your Project settings) in the project directory.
Kodiak, I see also you run multible occurances of a public static void ToChatBar
I thought this conflicted? How does it know which one to use?
I've overloaded the methods, they must differ in type or/and number of arguments. So the Compiler 'knows' which to use.
podvoxx
05-22-2012, 06:26 AM
Where do you store the file?
For multiplayer it must (should maybe there is another location too) be in "..\Steam\SteamApps\common\il-2 sturmovik cliffs of dover\parts\core" at the moment, until we can create Addins and specify the path of the User Dlls in the xml-file.
My folder in "..\Steam\SteamApps\common\il-2 sturmovik cliffs of dover\MyDLLfolder". In the evening try to change the folder location and add xml-file.
FG28_Kodiak
05-22-2012, 08:00 AM
Addins for multiplayer are ignored at the moment or some trick is needed - ok if you get it to work tell me please.
Smokeynz
05-22-2012, 09:52 AM
ok, I try to build project(your message above) but get errors, so add references of CLOD, then project won't build and create dll....hmmm
I tried to follow several guides on web, all say process much the same, but dont work because I seem to need references from CLOD, which seem to make the build step fail...sigh.
doing something wrong, not sure what.
FG28_Kodiak
05-22-2012, 10:42 AM
Add the references to the Clodo Assemblies (DLLs) to the project, described here:
http://forum.1cpublishing.eu/showthread.php?t=28997
Smokeynz
05-22-2012, 08:58 PM
Yes I did that, infact I repeated the process of reloading the assemblies several times.
Doing so removes the errors(red lines under your code above), but when I click "build" nothing happens.
Think I am missing a step somewhere.
FG28_Kodiak
05-23-2012, 10:18 AM
look at the bottom left corner of the Visual Studio Window, after you start the build.
FG28_Kodiak
05-23-2012, 12:21 PM
@podvoxx
btw. ive created a translation system, also:
I use a nested Dictionary to store the translation strings and fill it from a XML - File.
In the DLL (threadsafe Singleton Pattern):
using System;
using System.Collections.Generic;
using System.Xml;
namespace CoD
{
public sealed class Configuration
{
private static volatile Configuration _theOneAndOnly = null;
private readonly Dictionary<string, Dictionary<string, Dictionary<string, string>>> _stringPool = new Dictionary<string, Dictionary<string, Dictionary<string, string>>>();
private static object syncRoot = new object(); //nessesary for threadsave Singleton
const string XmlLanguagenode = "CloDo/LanguageSection";
private const string DefaultLanguage = "en";
public static Configuration GetInstance(string filename)
{
if (_theOneAndOnly == null)
{
lock (syncRoot)
{
if (_theOneAndOnly == null)
{
_theOneAndOnly = new Configuration(filename);
}
}
}
return _theOneAndOnly;
}
private Configuration(string filename)
{
LoadSettings(filename);
}
private 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 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 (texts.TryGetValue(language, out text))
return text;
if (texts.TryGetValue(DefaultLanguage, out text))
return text;
}
}
}
return ""; // 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);
}
}
}
in the mis (example
//$reference parts/core/CoD.dll
using System;
using System.Collections.Generic;
using maddox.game;
using maddox.game.world;
using CoD;
public class Mission : AMission
{
private static string userdocpath = Environment.GetFolderPath(Environment.SpecialFolde r.MyDocuments);
private static string FILE_PATH = userdocpath + @"\1C SoftClub\il-2 sturmovik cliffs of dover\";
private static string CONFIG_FILE = FILE_PATH + @"missions\tests\Language.xml";
private Configuration Config = Configuration.GetInstance(CONFIG_FILE);
enum toTarget
{
ChatAndScreen,
Chat,
Screen
}
private void send(IEnumerable<Player> players, string msgKey, toTarget target, params object[] args)
{
if (players == null) return;
foreach (Player pl in players)
{
switch (target)
{
case toTarget.ChatAndScreen:
GamePlay.gpLogServer(new[] { pl }, Config.GetString("Messages", msgKey, pl.LanguageName()), args);
GamePlay.gpHUDLogCenter(new[] { pl }, Config.GetString("Messages", msgKey, pl.LanguageName()), args);
break;
case toTarget.Chat:
GamePlay.gpLogServer(new[] { pl }, Config.GetString("Messages", msgKey, pl.LanguageName()), args);
break;
case toTarget.Screen:
GamePlay.gpHUDLogCenter(new[] { pl }, Config.GetString("Messages", msgKey, pl.LanguageName()), args);
break;
}
}
}
public void SetMainMenu(Player player)
{
if (GamePlay.gpPlayer() != null && player == GamePlay.gpPlayer())
GamePlay.gpSetOrderMissionMenu(player, false, 0, new string[] { Config.GetString("InGameMenu", "MainMenuItem1", player.LanguageName()), Config.GetString("InGameMenu", "MainMenuItem2", player.LanguageName()), Config.GetString("InGameMenu", "MainMenuItem3", player.LanguageName()) }, new bool[] { true, true, true });
else
GamePlay.gpSetOrderMissionMenu(player, false, 0, new string[] { Config.GetString("InGameMenu", "MainMenuItem1", player.LanguageName()), Config.GetString("InGameMenu", "MainMenuItem2", player.LanguageName()) }, new bool[] { true, true });
}
public override void OnOrderMissionMenuSelected(Player player, int ID, int menuItemIndex)
{
if (ID == 0)
{ // main menu
if (menuItemIndex == 1)
{
}
if (menuItemIndex == 2)
{
}
if (menuItemIndex == 3)
{
}
}
if (ID == 105)
{
if (menuItemIndex == 1)
{
}
}
}
public override void OnPlaceEnter(Player player, AiActor actor, int placeIndex)
{
base.OnPlaceEnter(player, actor, placeIndex);
send(new Player[] { player }, "successMission01_1", toTarget.ChatAndScreen);
send(new Player[] { player }, "successMission01_2", toTarget.Chat);
send(new Player[] { player }, "successMission02", toTarget.Chat);
send(new Player[] { player }, "successMission03", toTarget.Chat);
send(new Player[] { player }, "successMission04", toTarget.Chat);
send(new Player[] { player }, "successMission05_1", toTarget.Chat);
send(new Player[] { player }, "successMission05_2", toTarget.Chat);
send(new Player[] { player }, "successMission05_3", toTarget.Chat);
send(new Player[] { player }, "successMission06", toTarget.Chat);
SetMainMenu(player);
}
}
A example XML-File:
<?xml version="1.0" encoding="utf-8"?>
<!-- Sample XML - File for Translation -->
<CloDo>
<LanguageSection name="Messages">
<Text key="successMission01_1">
<en>Red side has destroyed blue artillery</en>
<ru>Команда красных уничтожила артиллерию синих</ru>
<de>Die rote Seite hat die blaue Artillerie zerstört</de>
</Text>
<Text key="successMission01_2">
<en>Red side has destroyed blue artillery supply</en>
<ru>Команда красных уничтожила снабжение артиллерии синих</ru>
<de>Die rote Seite hat den blauen Artillerie Nachschub zerstört</de>
</Text>
<Text key="successMission02">
<en>Red side has destroyed blue column</en>
<ru>Команда красных уничтожила автоколонну синих</ru>
<de>Die rote Seite hat blaue Kolonne zerstört</de>
</Text>
<Text key="successMission03">
<en>Red side has destroyed blue reconnaissance aircraft</en>
<ru>Команда красных уничтожила самолет-разведчик синих</ru>
<de>Die rote Seite hat blaues Aufklärungsflugzeug abgeschossen</de>
</Text>
<Text key="successMission04">
<en>Blue side has destroyed red column</en>
<ru>Команда синих уничтожила автоколонну красных</ru>
<de>Die blaue Seite hat rote Kolonne zerstört</de>
</Text>
<Text key="successMission05_1">
<en>Blue side has destroyed 30% of the convoy of red</en>
<ru>Команда синих уничтожила 30% конвоя красных</ru>
<de>Die blaue Seite hat 30% der roten Kolonne zerstört</de>
</Text>
<Text key="successMission05_2">
<en>Blue side has destroyed 60% of the convoy of red</en>
<ru>Команда синих уничтожила 60% конвоя красных</ru>
<de>Die blaue Seite hat 60% der roten Kolonne zerstört</de>
</Text>
<Text key="successMission05_3">
<en>Blue side has destroyed 100% of the convoy of red</en>
<ru>Команда синих уничтожила 100% конвоя красных</ru>
<de>Die blaue Seite hat 100% der roten Kolonne zerstört</de>
</Text>
<Text key="successMission06">
<en>Blue side has destroyed red tanks</en>
<ru>Команда синих уничтожила танковую дивизию красных</ru>
<de>Die blaue Seite hat die roten Panzer zerstört</de>
</Text>
</LanguageSection>
<LanguageSection name="InGameMenu">
<Text key="MainMenuItem1">
<de>Flugzeug auswählen</de>
<en>Plane selection</en>
</Text>
<Text key="MainMenuItem2">
<de>Gruppen Befehle</de>
<en>Group Orders</en>
</Text>
<Text key="MainMenuItem3">
<de>Hoster Befehle</de>
<en>Host Orders</en>
</Text>
</LanguageSection>
</CloDo>
Advantages you can add new languages simply, if the language is not found a default language is used, in my example the english one (specifie in DLL).
podvoxx
05-23-2012, 02:58 PM
@podvoxx
btw. ive created a translation system, also:
Big thanks, Kodiak! Now I use Small_bee loc. system
http://www.sukhoi.ru/forum/showthread.php?t=72108&p=1765804&viewfull=1#post1765804
Maybe this system will be use in repka comander - http://www.sukhoi.ru/forum/showthread.php?t=75862
About my DLL, it not work:(
My script:
//$reference "parts\core\SMP\SMPlocalization.dll"
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using maddox.game;
using maddox.game.world;
using maddox.GP;
using locfiledll;
public class Mission : AMission
{
public override void OnPlaceEnter(Player player, AiActor actor, int placeIndex)
{
base.OnPlaceEnter(player, actor, placeIndex);
localization.ToChatbar(player, "Welcome {0}", player);
}
}
Path to dll-file: parts\core\SMP\SMPlocalization.dll
My dll-file:
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Diagnostics;
using maddox.game;
using maddox.game.world;
using maddox.GP;
using part;
namespace locfiledll
{
public static class localization
{
static readonly IGamePlay GamePlay = Strategy.THIS.GamePlay;
public static void ToChatbar(string msg, params object[] args)
{
GamePlay.gpLogServer(null, msg, args);
}
public static void ToChatbar(Player player, string msg, params object[] args)
{
if (player != null)
GamePlay.gpLogServer(new[] { player }, msg, args);
}
public static void ToChatbar(int army, string msg, params object[] args)
{
var consignees = new List<Player>();
if (GamePlay.gpPlayer() != null)
consignees.Add(GamePlay.gpPlayer());
if (GamePlay.gpRemotePlayers() != null)
consignees.AddRange(GamePlay.gpRemotePlayers());
if (army == -1)
GamePlay.gpLogServer(null, msg, args);
else if (consignees.Exists(item => item.Army() == army))
GamePlay.gpLogServer(consignees.FindAll(item => item.Army() == army).ToArray(), msg, args);
}
public static void ToScreen(string msg, params object[] args)
{
GamePlay.gpHUDLogCenter(null, msg, args);
}
public static void ToScreen(Player player, string msg, params object[] args)
{
if (player != null)
GamePlay.gpHUDLogCenter(new[] { player }, msg, args);
}
}
}
After calling OnPlaceEnter method I have this error:
[18:42:32] =================================================
[18:42:32] System.IO.FileNotFoundException: Could not load file or assembly 'SMPlocalization, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. Не удается найти указанный файл.
[18:42:32] File name: 'SMPlocalization, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'
[18:42:32]
[18:42:32] Server stack trace:
[18:42:32] at Mission.OnPlaceEnter(Player player, AiActor actor, Int32 placeIndex)
[18:42:32] at maddox.game.ABattle.OnPlaceEnter(Player player, AiActor actor, Int32 placeIndex)
[18:42:32] at maddox.game.ABattle.OnEventGame(GameEventId eventId, Object eventArg0, Object eventArg1, Int32 eventArgInt)
[18:42:32] at maddox.game.world.Strategy.OnEventGame(GameEventId eventId, Object eventArg0, Object eventArg1, Int32 eventArgInt)
[18:42:32] at System.Runtime.Remoting.Messaging.StackBuilderSink ._PrivateProcessMessage(IntPtr md, Object[] args, Object server, Int32 methodPtr, Boolean fExecuteInContext, Object[]& outArgs)
[18:42:32] at System.Runtime.Remoting.Messaging.StackBuilderSink .SyncProcessMessage(IMessage msg, Int32 methodPtr, Boolean fExecuteInContext)
[18:42:32]
[18:42:32] Exception rethrown at [0]:
[18:42:32] at System.Runtime.Remoting.Proxies.RealProxy.HandleRe turnMessage(IMessage reqMsg, IMessage retMsg)
[18:42:32] at System.Runtime.Remoting.Proxies.RealProxy.PrivateI nvoke(MessageData& msgData, Int32 type)
[18:42:32] at maddox.game.IBattle.OnEventGame(GameEventId eventId, Object eventArg0, Object eventArg1, Int32 eventArgInt)
[18:42:32] at maddox.game.GameDef.eventGame(GameEventId eventId, Object eventArg0, Object eventArg1, Int32 eventArgInt)
[18:42:32] at QS9s5gXYpyXIbWqUeH5.NEqYCeXQeE9aADb49yZ.LNESqn0gob x(GameEventId , Object , Object , Int32 )
[18:42:32]
[18:42:32] WRN: Assembly binding logging is turned OFF.
[18:42:32] To enable assembly bind failure logging, set the registry value [HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) to 1.
[18:42:32] Note: There is some performance penalty associated with assembly bind failure logging.
[18:42:32] To turn this feature off, remove the registry value [HKLM\Software\Microsoft\Fusion!EnableLog].
[18:42:32]
[18:42:32] =================================================
FG28_Kodiak
05-23-2012, 03:03 PM
place your DLL in ..parts\core
and use this:
//$reference parts\core\SMPlocalization.dll
then it should work. ;)
podvoxx
05-23-2012, 03:11 PM
place your DLL in ..parts\core
and use this:
//$reference parts\core\SMPlocalization.dll
then it should work. ;)
Yes, I have already corrected. It works! :)
Thank you!
Smokeynz
05-24-2012, 09:31 PM
I've been using txt files, but the problem is you have to streamread and relist and index internally, it works but is kinda resource hungry.
I really like the dll and xml combination, "find it and use it when needed".
Also means you could just about centralise repeat type messaging used across multi mission packs.
Also arguably a bit more user friendly in that more ppl are used to xml editing for simple configs.
podvoxx
07-05-2012, 08:37 AM
@podvoxx
btw. ive created a translation system, also:
I use a nested Dictionary to store the translation strings and fill it from a XML - File.
I create new message system whith translate function, but I have some problem.
In your script:
private Configuration Config = Configuration.GetInstance(CONFIG_FILE);
...
Config.GetString("Messages", msgKey, pl.LanguageName());
In my script:
private SendTranslate initTranslate = SendTranslate.GetInstance(localizationFilePath);
I can't use:
initTranslate.GetString("Messages", msgKey, pl.LanguageName())
I can use only:
SendTranslate.GetString("Messages", msgKey, pl.LanguageName(), "Chat")
It's ptoblem whith static methods in dll-file:
public static string GetString(string section, string key, string language)
If I change to none-static field, I have error on this method:
private static void Send(Player[] playerList, string section, string key, string target, params object[] args)
What I need to do for fix this trouble? I need use code in my mission scripts as on you script type:
initTranslate.GetString("Messages", msgKey, pl.LanguageName())
My dll.file:
using System;
using System.IO;
using System.Collections;
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 SendTranslate
{
#region Parameters
private static volatile SendTranslate _theOneAndOnly = null;
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;
private static object syncRoot = new object(); //nessesary for threadsave Singleton
const string XmlLanguagenode = "SMP/LanguageSection";
private const string DefaultLanguage = "en";
public static string setupServerLanguage = "en";
public static string hudON = "on";
#endregion
#region Read File
public static SendTranslate GetInstance(string filename)
{
if (_theOneAndOnly == null)
{
lock (syncRoot)
{
if (_theOneAndOnly == null)
{
_theOneAndOnly = new SendTranslate(filename);
}
}
}
return _theOneAndOnly;
}
private SendTranslate(string filename)
{
LoadSettings(filename);
}
private 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 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 static 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 (texts.TryGetValue(language, 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 static void ToAll(string section, string key, string target, params object[] args)
{
Send(SendMessage.GetPlayerList(1), section, key, target, args);
Send(SendMessage.GetPlayerList(2), section, key, target, args);
}
public static void ToArmy(string section, string key, int army, string target, params object[] args)
{
Send(SendMessage.GetPlayerList(army), section, key, target, args);
}
public static void ToPlayers(string section, string key, Player[] players, string target, params object[] args)
{
Send(players, section, key, target, args);
}
#endregion
#region Send
private static void Send(Player[] playerList, string section, string key, string target, params object[] args)
{
Dictionary<string, List<Player>> playerLanguageDict = new Dictionary<string, List<Player>>();
List<Player> serverList = new List<Player>();
string serverLanguageName = "en";
if (GamePlay.gpPlayer() != null)
{
serverList.Add(GamePlay.gpPlayer());
}
foreach (Player player in playerList)
{
string languageName = player.LanguageName();
if (!playerLanguageDict.ContainsKey(languageName))
{
playerLanguageDict.Add(languageName, new List<Player>());
}
playerLanguageDict[languageName].Add(player);
}
if (serverList.Count > 0)
{
foreach (Player serverPlayer in serverList)
{
serverLanguageName = serverPlayer.LanguageName();
if (setupServerLanguage != "off")
{
serverLanguageName = setupServerLanguage;
}
}
if (target == "Screen" && hudON == "on")
{
GamePlay.gpLogServer(serverList.ToArray(), "[HUD]:" + GetString(section, key, serverLanguageName), args);
}
else
{
GamePlay.gpLogServer(serverList.ToArray(), GetString(section, key, serverLanguageName), args);
}
}
if (playerList.Length > 0)
{
foreach (KeyValuePair<string, List<Player>> kvp in playerLanguageDict)
{
switch (target)
{
case "ChatAndScreen":
{
GamePlay.gpLogServer(kvp.Value.ToArray(), GetString(section, key, kvp.Key.ToString()), args);
GamePlay.gpHUDLogCenter(kvp.Value.ToArray(), GetString(section, key, kvp.Key.ToString()), args);
} break;
case "Chat": GamePlay.gpLogServer(kvp.Value.ToArray(), GetString(section, key, kvp.Key.ToString()), args); break;
case "Screen": GamePlay.gpHUDLogCenter(kvp.Value.ToArray(), GetString(section, key, kvp.Key.ToString()), args); break;
}
}
}
}
#endregion
}
public static class SendMessage
{
#region Parameters
static readonly IGamePlay GamePlay = Strategy.THIS.GamePlay;
public static string hudON = "on";
#endregion
#region Send Message to List
public static void ToAll(string message, string target, params object[] args)
{
Send(GetPlayerList(1), message, target, args);
Send(GetPlayerList(2), message, target, args);
}
public static void ToArmy(string message, int army, string target, params object[] args)
{
Send(GetPlayerList(army), message, target, args);
}
public static void ToPlayers(string message, Player[] players, string target, params object[] args)
{
Send(players, message, target, args);
}
#endregion
#region Send
private static void Send(Player[] playerList, string message, string target, params object[] args)
{
List<Player> serverList = new List<Player>();
if (GamePlay.gpPlayer() != null)
{
serverList.Add(GamePlay.gpPlayer());
}
if (serverList.Count > 0)
{
if (target == "Screen" && hudON == "on")
{
GamePlay.gpLogServer(serverList.ToArray(), "[HUD]:" + message, args);
}
else
{
GamePlay.gpLogServer(serverList.ToArray(), message, 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); break;
}
}
}
#endregion
#region GetPlayerList
public static Player[] GetPlayerList(int army)
{
List<Player> playerList = new List<Player>();
List<Player> playerArmyList = new List<Player>();
if (GamePlay.gpPlayer() != null)
playerList.Add(GamePlay.gpPlayer());
if (GamePlay.gpRemotePlayers() != null)
playerList.AddRange(GamePlay.gpRemotePlayers());
if (playerList != null)
{
foreach (Player player in playerList)
{
if (player.Army() == army && player != null)
playerArmyList.Add(player);
}
}
return playerArmyList.ToArray();
}
#endregion
}
}
And example .cs:
//$reference "smpMessage.dll"
using System;
using maddox.game;
using maddox.game.world;
using smpmessage;
/* 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)
*
* -- 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.SpecialFolde r.Personal) + "\\1C SoftClub\\il-2 sturmovik cliffs of dover\\missions\\Single\\LocalizationExample\\loca lization.xml";
// Create dictionary for translate and send messages
private SendTranslate initTranslate = SendTranslate.GetInstance(localizationFilePath);
public override void OnBattleStarted()
{
base.OnBattleStarted();
MissionNumberListener = -1;
}
public override void OnPlaceEnter(Player player, AiActor actor, int placeIndex)
{
base.OnPlaceEnter(player, actor, placeIndex);
initTranslate.GetString("SendMessageSection", "GetTranslateText", "en");
// TEST Messages
// Translate and send message
/*
initTranslate.ToAll("SendMessageSection", "SendToChatToALLtranslate", "Chat");
initTranslate.ToPlayers("SendMessageSection", "SendToChatToPlayertranslate", new Player[] { player }, "Chat");
initTranslate.ToArmy("SendMessageSection", "SendToChatToArmytranslate", 1, "Chat");
initTranslate.ToAll("SendMessageSection", "SendToScreenToALLtranslate", "Screen");
initTranslate.ToPlayers("SendMessageSection", "SendToScreenToPlayertranslate", new Player[] { player }, "Screen");
initTranslate.ToArmy("SendMessageSection", "SendToScreenToArmytranslate", 1, "Screen");
initTranslate.ToAll("SendMessageSection", "SendToChatAndScreenToALLtranslate", "ChatAndScreen");
initTranslate.ToPlayers("SendMessageSection", "SendToChatAndScreenToPlayertranslate", new Player[] { player }, "ChatAndScreen");
initTranslate.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(initTranslate.GetString("SendMessageSection", "GetTranslateText", "en"), "Chat");
SendMessage.ToAll(initTranslate.GetString("SendMessageSection", "GetTranslateText", player.LanguageName()), "Chat");
SendMessage.ToAll(initTranslate.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.ToAll("============NO TRANSLATE LINE whithout xml-file===========", "Chat");
}
}
xml:
<?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>
FG28_Kodiak
07-06-2012, 05:28 AM
Will take a look at ir.
FG28_Kodiak
07-06-2012, 08:07 AM
Ok, made some changes:
The dll:
using System;
using System.Collections.Generic;
using System.Xml;
using maddox.game;
using maddox.game.world;
namespace smpmessage
{
public sealed class Translations
{
private static readonly Lazy<Translations> Lazy = new Lazy<Translations>(() => new Translations());
private static readonly Dictionary<string, Dictionary<string, Dictionary<string, string>>> _stringPool =
new Dictionary<string, Dictionary<string, Dictionary<string, string>>>();
private const string XmlLanguagenode = "SMP/LanguageSection";
private const string DefaultLanguage = "en";
public static Translations GetInstance
{
get { return Lazy.Value; }
}
private Translations()
{
}
public static Translations UseConfigFile(string fileName)
{
if (_stringPool.Count == 0)
LoadSettings(fileName);
return Lazy.Value;
}
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);
}
}
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;
}
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 (texts.TryGetValue(language, 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);
}
}
public static class SendMessage
{
private static readonly IGamePlay GamePlay = Strategy.THIS.GamePlay;
private static Translations Translator = Translations.GetInstance; //Reference to the Singleton Class
public static string setupServerLanguage = "en";
public static string hudON = "on";
public static void ToAll(string message, string target, params object[] args)
{
Send(GetPlayerList(1), message, target, args);
Send(GetPlayerList(2), message, target, args);
}
public static void ToArmy(string message, int army, string target, params object[] args)
{
Send(GetPlayerList(army), message, target, args);
}
public static void ToPlayers(string message, Player[] players, string target, params object[] args)
{
Send(players, message, target, args);
}
private static void Send(Player[] playerList, string message, string target, params object[] args)
{
List<Player> serverList = new List<Player>();
if (GamePlay.gpPlayer() != null)
{
serverList.Add(GamePlay.gpPlayer());
}
if (serverList.Count > 0)
{
if (target == "Screen" && hudON == "on")
{
GamePlay.gpLogServer(serverList.ToArray(), "[HUD]:" + message, args);
}
else
{
GamePlay.gpLogServer(serverList.ToArray(), message, 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);
break;
}
}
}
public static Player[] GetPlayerList(int army)
{
List<Player> playerList = new List<Player>();
List<Player> playerArmyList = new List<Player>();
if (GamePlay.gpPlayer() != null)
playerList.Add(GamePlay.gpPlayer());
if (GamePlay.gpRemotePlayers() != null)
playerList.AddRange(GamePlay.gpRemotePlayers());
if (playerList != null)
{
foreach (Player player in playerList)
{
if (player.Army() == army && player != null)
playerArmyList.Add(player);
}
}
return playerArmyList.ToArray();
}
public static void ToAll(string section, string key, string target, params object[] args)
{
Send(SendMessage.GetPlayerList(1), section, key, target, args);
Send(SendMessage.GetPlayerList(2), section, key, target, args);
SendMessage.GetPlayerList(1);
}
public static void ToArmy(string section, string key, int army, string target, params object[] args)
{
Send(SendMessage.GetPlayerList(army), section, key, target, args);
}
public static void ToPlayers(string section, string key, Player[] players, string target, params object[] args)
{
Send(players, section, key, target, args);
}
private static void Send(Player[] playerList, string section, string key, string target, params object[] args)
{
Dictionary<string, List<Player>> playerLanguageDict = new Dictionary<string, List<Player>>();
List<Player> serverList = new List<Player>();
string serverLanguageName = "en";
if (GamePlay.gpPlayer() != null)
{
serverList.Add(GamePlay.gpPlayer());
}
foreach (Player player in playerList)
{
string languageName = player.LanguageName();
if (!playerLanguageDict.ContainsKey(languageName))
{
playerLanguageDict.Add(languageName, new List<Player>());
}
playerLanguageDict[languageName].Add(player);
}
if (serverList.Count > 0)
{
foreach (Player serverPlayer in serverList)
{
serverLanguageName = serverPlayer.LanguageName();
if (setupServerLanguage != "off")
{
serverLanguageName = setupServerLanguage;
}
}
if (target == "Screen" && hudON == "on")
{
GamePlay.gpLogServer(serverList.ToArray(),
"[HUD]:" + Translator.GetString(section, key, serverLanguageName), args);
}
else
{
GamePlay.gpLogServer(serverList.ToArray(), Translator.GetString(section, key, serverLanguageName),
args);
}
}
if (playerList.Length > 0)
{
foreach (KeyValuePair<string, List<Player>> kvp in playerLanguageDict)
{
switch (target)
{
case "ChatAndScreen":
{
GamePlay.gpLogServer(kvp.Value.ToArray(),
Translator.GetString(section, key, kvp.Key), args);
GamePlay.gpHUDLogCenter(kvp.Value.ToArray(),
Translator.GetString(section, key, kvp.Key), args);
}
break;
case "Chat":
GamePlay.gpLogServer(kvp.Value.ToArray(),
Translator.GetString(section, key, kvp.Key), args);
break;
case "Screen":
GamePlay.gpHUDLogCenter(kvp.Value.ToArray(),
Translator.GetString(section, key, kvp.Key), args);
break;
}
}
}
}
}
}
Test cs (Mission file):
//$reference smpmessage.dll
using System;
using maddox.game;
using maddox.game.world;
using smpmessage;
/* 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)
*
* -- 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.SpecialFolde r.Personal) + "\\1C SoftClub\\il-2 sturmovik cliffs of dover\\missions\\Single\\LocalizationExample\\loca lization.xml";
// Load Languagefile for use in Message
private Translations Translator = Translations.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);
string testmsg = "TestMessage: " + Translator.GetString("SendMessageSection", "GetTranslateText", "en");
GamePlay.gpLogServer(null, testmsg, null);
SendMessage.ToAll("SendMessageSection", "GetTranslateText", "en");
SendMessage.ToAll("SendMessageSection", "SendToChatToALLtranslate", "Chat");
SendMessage.ToPlayers("SendMessageSection", "SendToChatToPlayertranslate", new Player[] { player }, "Chat");
SendMessage.ToArmy("SendMessageSection", "SendToChatToArmytranslate", 1, "Chat");
SendMessage.ToAll("SendMessageSection", "SendToScreenToALLtranslate", "Screen");
SendMessage.ToPlayers("SendMessageSection", "SendToScreenToPlayertranslate", new Player[] { player }, "Screen");
SendMessage.ToArmy("SendMessageSection", "SendToScreenToArmytranslate", 1, "Screen");
SendMessage.ToAll("SendMessageSection", "SendToChatAndScreenToALLtranslate", "ChatAndScreen");
SendMessage.ToPlayers("SendMessageSection", "SendToChatAndScreenToPlayertranslate", new Player[] { player }, "ChatAndScreen");
SendMessage.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(initTranslate.GetString("SendMessageSection", "GetTranslateText", "en"), "Chat");
SendMessage.ToAll(initTranslate.GetString("SendMessageSection", "GetTranslateText", player.LanguageName()), "Chat");
SendMessage.ToAll(initTranslate.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.ToAll("============NO TRANSLATE LINE whithout xml-file===========", "Chat");
}
}
What modified:
Changed the old singleton implementation to a better one (without double locking) and renamed it to Translations
Moved the translationsMessages to the sendMessage Class. Added reference to the Singleton Translations "private static Translations Translator = Translations.GetInstance;" so GetString() could used in the sendMessage class (Translator.GetString(...))
Added a UseConfigFile to the singleton to load the language file later (in cs from mission).
To load the Translationsfile into the singleton use:
private Translations Translator = Translations.UseConfigFile(localizationFilePath);
in mission file cs.
Should work now, couldn't test it at work, only short time in coffee break for modifications :rolleyes:
podvoxx
07-06-2012, 08:17 AM
Should work now, couldn't test it at work, only short time in coffee break for modifications :rolleyes:
Great thanks, Kodiak! I try this version later.
podvoxx
07-07-2012, 01:00 PM
Yes, it work :) Big thanks, Kodiak!
I modify your and my code and get this:
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, target, args);
break;
}
case "Screen":
{
Send(SendMessage.GetPlayerListScreenAll(), section, key, target, 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);
}
#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();
}
#endregion
}
}
vBulletin® v3.8.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.