Sign in to follow this  
Followers 0
guinness

C# - Rot13

5 posts in this topic

Maybe other ideas will follow.

using System;
using System.Collections.Generic;

namespace Rot13
{
    internal class Program
    {
        public static void Main()
        {
            Rot13 rot13 = new Rot13(); // Create a rotation 13 object.
            string encodedString = rot13.Encode("Rotate this string."); // Encode the string.
            Console.WriteLine("Encoded string: {0}", encodedString);

            string decodedString = rot13.Decode(encodedString); // Decode the rotated string.
            Console.WriteLine("Decoded string: {0}", decodedString);

            Console.WriteLine(""); // Create a new line.

            Console.Write("Press any key to continue . . . ");
            Console.ReadKey(true);
        }
    }

    public class Rot13
    {
        private Dictionary<char, char> rot13 = new Dictionary<char, char>();

        /// <summary>
        /// Initialise the dictionary on a per object basis. I guess it could be made static as well?!
        /// </summary>
        public Rot13()
        {
            string lowLower = "abcdefghijklm", highLower = "nopqrstuvwxyz";
            string lowUpper = "ABCDEFGHIJKLM", highUpper = "NOPQRSTUVWXYZ";

            for (int i = 0; i < lowUpper.Length; i++)
            {
                // Convert a => n and A => N.
                rot13.Add(lowLower[i], highLower[i]);
                rot13.Add(highLower[i], lowLower[i]);

                // Convert n => a and N => A.
                rot13.Add(lowUpper[i], highUpper[i]);
                rot13.Add(highUpper[i], lowUpper[i]);
            }
        }

        /// <summary>
        /// Decode a Rot13 string.
        /// </summary>
        /// <param name="data">A Rot13 encoded string.</param>
        /// <returns>The original string.</returns>
        public string Decode(string data)
        {
            return Encode(data);
        }

        /// <summary>
        /// Encode a string to using Rot13.
        /// </summary>
        /// <param name="data">A string to be encoded.</param>
        /// <returns>An encoded string.</returns>
        public string Encode(string data)
        {
            char rotated = new char();
            char[] array = data.ToCharArray();
            for (int i = 0; i < array.Length; i++)
            {
                if (rot13.TryGetValue(array[i], out rotated))
                {
                    array[i] = rotated;
                }
            }
            return new string(array);
        }
    }
}

_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 04/09/2015

Share this post


Link to post
Share on other sites

You don't need to initialize variables used with 'out'. You can just declare them as 'out' counts as initialization.

Faster method would be to check the numeric value of the characters.

char[] array = data.ToCharArray();
char value;
for (int i = 0; i < data.Length; i++)
{
    value = data[i];
    if ((value >= 'a' && value <= 'm') || (value >= 'A' && value <= 'M'))
        array[i] = value + 13;
    else if ((value >= 'n' && value <= 'z') || (value >= 'N' && value <= 'Z'))
        array[i] = value - 13;
}
return new string(array);

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Thanks for the out tip. Just a bad force of habit.

I was wondering if that method was faster or not. By the way, why didn't you declare value inside the loop? I read that it doesn't affect execution if you declare in loop scope.

Edited by guinness

_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 04/09/2015

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Function-local variables in .Net are always allocated as part of the function before any line of code executes. This is internal behavior that I am familiar with so I tend to declare everything at the top of the function so that the C# matches the framework code. Notice I said allocated and not assigned. Assignment obviously takes place in code order.

The speed difference should be noticeable with just a millisecond timer. It doesn't do any extra function calls or dictionary lookups like your original does. Since characters are integers, using integral comparison operators is valid.

Edited by Richard Robertson

Share this post


Link to post
Share on other sites

Gotcha.


_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 04/09/2015

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0

  • Similar Content

    • JLogan3o13
      By JLogan3o13
      Not one usually to post non-AutoIt things, but as I have this question on StackExchange I thought I would throw it up here as well for any of our C# folks:
      I currently have an AutoIt GUI that calls a powershell script; the intent is to allow low-level technicians to batch create VMs in vSphere. Due to some changes in requirements from the customer, I am re-writing as a wpf app. The app itself is complete and working; this is more of a curiosity question.
      I have two methods attached to buttons on the GUI - one to pull all the data out of a listview and export to csv and another to do the reverse; importing from csv to the listview element. I wrote the export first, and went with manipulating the Excel application:
      private void Launch(object sender, RoutedEventArgs e) { Microsoft.Office.Interop.Excel.Application oExcel = new Microsoft.Office.Interop.Excel.Application(); oExcel.Visible = true; Microsoft.Office.Interop.Excel.Workbook oWorkBook = oExcel.Workbooks.Add(Microsoft.Office.Interop.Excel.XlSheetType.xlWorksheet); Microsoft.Office.Interop.Excel.Worksheet oSheet = (Microsoft.Office.Interop.Excel.Worksheet)oExcel.ActiveSheet; int row = 2; //allow for header row int column = 1; oSheet.Cells[1, 1] = "Name"; oSheet.Cells[1, 2] = "CPU"; oSheet.Cells[1, 3] = "RAM"; oSheet.Cells[1, 4] = "IP Address"; oSheet.Cells[1, 5] = "Subnet Mask"; oSheet.Cells[1, 6] = "Port Group"; oSheet.Cells[1, 7] = "Default Gateway"; oSheet.Cells[1, 8] = "DNS"; oSheet.Cells[1, 9] = "Description"; oSheet.Cells[1, 10] = "Template"; oSheet.Cells[1, 11] = "Host"; oSheet.Cells[1, 12] = "Site"; oSheet.Cells[1, 13] = "Folder"; oSheet.Cells[1, 14] = "DataStore"; oSheet.Cells[1, 15] = "Patch Method"; oSheet.Cells[1, 16] = "HDD1Size"; oSheet.Cells[1, 17] = "HDD1Format"; oSheet.Cells[1, 18] = "HDD2Size"; oSheet.Cells[1, 19] = "HDD2Format"; oSheet.Cells[1, 20] = "HDD3Size"; oSheet.Cells[1, 21] = "HDD3Format"; oSheet.Cells[1, 22] = "HDD4Size"; oSheet.Cells[1, 23] = "HDD4Format"; oSheet.Cells[1, 24] = "HDD5Size"; oSheet.Cells[1, 25] = "HDD5Format"; foreach (var oVM in MyItems) { oSheet.Cells[row, column] = oVM.Name; oSheet.Cells[row, (column + 1)] = oVM.CPU; oSheet.Cells[row, (column + 2)] = oVM.RAM; oSheet.Cells[row, (column + 3)] = oVM.IP; oSheet.Cells[row, (column + 4)] = oVM.Subnet; oSheet.Cells[row, (column + 5)] = oVM.PortGroup; oSheet.Cells[row, (column + 6)] = oVM.Gateway; oSheet.Cells[row, (column + 7)] = oVM.DNS; oSheet.Cells[row, (column + 8)] = oVM.Description; oSheet.Cells[row, (column + 9)] = oVM.Template; oSheet.Cells[row, (column + 10)] = oVM.Host; oSheet.Cells[row, (column + 11)] = oVM.Site; oSheet.Cells[row, (column + 12)] = oVM.Folder; oSheet.Cells[row, (column + 13)] = oVM.Datastore; oSheet.Cells[row, (column + 14)] = oVM.Patch; oSheet.Cells[row, (column + 15)] = oVM.HDD1Size; oSheet.Cells[row, (column + 16)] = oVM.HDD1Format; oSheet.Cells[row, (column + 17)] = oVM.HDD2Size; oSheet.Cells[row, (column + 18)] = oVM.HDD2Format; oSheet.Cells[row, (column + 19)] = oVM.HDD3Size; oSheet.Cells[row, (column + 20)] = oVM.HDD3Format; oSheet.Cells[row, (column + 21)] = oVM.HDD4Size; oSheet.Cells[row, (column + 22)] = oVM.HDD4Format; oSheet.Cells[row, (column + 23)] = oVM.HDD5Size; oSheet.Cells[row, (column + 24)] = oVM.HDD5Format; row++; } oExcel.Application.ActiveWorkbook.SaveAs(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + "\\example", 6); } It works, but it is slow. I have Excel set to visible for testing, and it is a good 6 or 7 seconds on a pretty high end box before the app even pops up.  It then takes another 2 seconds to populate 11 rows (this could be in the hundreds of rows at some point).
      I then wrote the code for the reverse, and decided to try a StreamReader object. The result, surprisingly, was almost immediate:
      OpenFileDialog xls = new OpenFileDialog(); xls.Multiselect = false; xls.Filter = "CSV files (*.csv)|*.csv"; xls.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory); xls.ShowDialog(); string ins; if (xls.FileName != null) { FileStream srcFS; srcFS = new FileStream(xls.FileName, FileMode.Open); StreamReader srcSR = new StreamReader(srcFS, System.Text.Encoding.Default); do { ins = srcSR.ReadLine(); if (ins != null) { string[] parts = ins.Split(','); MyItems.Add(new MyItem { Name = parts[0], CPU = parts[1], RAM = parts[2], IP = parts[3], Subnet = parts[4], PortGroup = parts[5], Gateway = parts[6], DNS = parts[7], Description = parts[8], Template = parts[9], Host = parts[10], Site = parts[11], Folder = parts[12], Datastore = parts[13], Patch = parts[14], HDD1Size = parts[15], HDD1Format = parts[16], HDD2Size = parts[17], HDD2Format = parts[18], HDD3Size = parts[19], HDD3Format = parts[20], HDD4Size = parts[21], HDD4Format = parts[22], HDD5Size = parts[23], HDD5Format = parts[24] }); } } while (ins != null); srcSR.Close(); } }  
      So, I thought I would go back and change the export to use the same method:
      FileStream srcFS; srcFS = new FileStream(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + "\\testingout.csv", FileMode.CreateNew, FileAccess.Write); StreamWriter srcWrt = new StreamWriter(srcFS, System.Text.Encoding.Default); StringBuilder header = new StringBuilder(); header.Append("Name").Append(',') .Append("CPU").Append(',') .Append("RAM").Append(',') .Append("IP Address").Append(',') .Append("Port Group").Append(',') .Append("Default Gateway").Append(',') .Append("DNS").Append(',') .Append("Description").Append(',') .Append("Template").Append(',') .Append("Host").Append(',') .Append("Site").Append(',') .Append("Folder").Append(',') .Append("Datastore").Append(',') .Append("Patch").Append(',') .Append("HDD1Size").Append(',') .Append("HDD1Format").Append(',') .Append("HDD2Size").Append(',') .Append("HDD2Format").Append(',') .Append("HDD3Size").Append(',') .Append("HDD3Format").Append(',') .Append("HDD4Size").Append(',') .Append("HDD4Format").Append(',') .Append("HDD5Size").Append(',') .Append("HDDFormat").Append(','); srcWrt.WriteLine(header); foreach (MyItem item in MyItems) { StringBuilder builder = new StringBuilder(); builder.Append(item.Name).Append(',') .Append(item.CPU).Append(',') .Append(item.RAM).Append(',') .Append(item.IP).Append(',') .Append(item.Subnet).Append(',') .Append(item.PortGroup).Append(',') .Append(item.Gateway).Append(',') .Append(item.DNS).Append(',') .Append(item.Description).Append(',') .Append(item.Template).Append(',') .Append(item.Host).Append(',') .Append(item.Site).Append(',') .Append(item.Folder).Append(',') .Append(item.Datastore).Append(',') .Append(item.Patch).Append(',') .Append(item.HDD1Size).Append(',') .Append(item.HDD1Format).Append(',') .Append(item.HDD2Size).Append(',') .Append(item.HDD2Format).Append(',') .Append(item.HDD3Size).Append(',') .Append(item.HDD3Format).Append(',') .Append(item.HDD4Size).Append(',') .Append(item.HDD4Format).Append(',') .Append(item.HDD5Size).Append(',') .Append(item.HDD5Format); srcWrt.WriteLine(builder); } MessageBox.Show("Task Complete"); What surprised me is this method is exponentially slower; on the order of 40 seconds to return the MsgBox. I also noticed that even though the loop is complete and shows the message, is seems the stream is still writing. If I open the file too quickly it shows that it is still in use by "Another User". So by the time the file is available to me it is actually closer to a minute for an 11-line csv.
      I'm just curious at the difference in speed read vs write using FileStream. Is it something I borked on implementation (eminently possible) or is this a known issue? If interacting with Excel is the way to go (not ideal) is there something I could do to shorten the initial lag?
    • Luigi
      By Luigi
      Greetings, someone can give a exemple, how send a error from a C#'s dll to AutoIt?
      I use this line, to send an error... but, I want get a error code In AutoIt with macro @error, it's possible?
       
      throw new ArgumentException("arquivo map não existe", "value" ); In this way, work, I know ther are error, but, @errror always is zero.
      I don't want this, I want a number as error code.
      Can you help me?
       
      Best regards
    • breakbadsp
      By breakbadsp
      AutoIT AU3info doeas not detect all gui objects uniquely for .NET GUIs developed in C#.
      this is not working now i am using COM windows approach for this, But its very difficult.
      Please let me know if anyone has done it before.
    • 5ervant
      By 5ervant
      What's the best way to receive file from a desktop app?
      app.exe will execute a cmd with "au3file.exe /path/of/the/file.xml" and the au3file.exe will get and delete that. Or else? THE MOST IMPORTANT PART OF THE QUESTION
      And best way to transfer file to a desktop app?
      au3file.exe do a $_POST request and the app.exe MUST HAVE a local HTTP server that can receive $_POST, but it looks heavy 'cause the app must have a server such XAMPP. au3file.exe execute a cmd with "app.exe /path/of/the/file.xml" and the app.exe will now get that file and delete. Or else?  
    • ALIENQuake
      By ALIENQuake
      Hello everyone,
      Finally I decide to ask hard question about one of the project which I currently maintain:
      Big World Setup aka mod installer for infinity engine games like BG, IWD, PST etc
      Project page: https://bitbucket.org/BigWorldSetup/bigworldsetup/overview
      More screenshot: https://forums.beamdog.com/discussion/44476/tool-big-world-setup-bws-mod-manager-for-baldurs-gate-enhanced-edition-trilogy-for-windows/p1
      General Features
      downloading mods (please see remarks!) easy mod installation correct install order of mods/components handle mod and components conflicts and auto solve them easy backup creation/restoring ability to add you own mods Internal Features (every single feature which you see here is already working in autoit)
       
      It look as simple GUI application but it has quite complicated logic regarding "handle mod and components conflicts and auto solve them" - this is most important feature of the app.
      This app needs to be converted into multi-platform GUI application because Enhanced Editions of the game can be played on OSX and Linux also. But for the past 6 years, there wasn't a single gamer/developer who would try to convert this app using multi-platform language and GUI. 
      This is the moment when I'm asking for help:
      - Which language would suit the best for multi-platform GUI application?  c#,python,java or other?
      - Is there any general approach for such conversion? 
      - Does autoit community/developer have some experience with converting autoit GUI applications into multi-platform GUI app by using multi-platform language like c#,python,java
      - Is there someone who isn't scared by looking at the source code of the application and feature list to help me with converting or even begin with creating multi-platform GUI app template which will just simply run the same commandline for every system ? 
      If there is something else which you would know, pleas ask and I will try to answer my best.