AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   New Plugin Submissions (https://forums.alliedmods.net/forumdisplay.php?f=26)
-   -   Multi-Mod Manager v1.1-release_candidate1.hotfix1 | Last Update: 21.01.2016 (https://forums.alliedmods.net/showthread.php?t=273020)

addons_zz 10-10-2015 22:41

Multi-Mod Manager v1.1-release_candidate1.hotfix1 | Last Update: 21.01.2016
 
3 Attachment(s)

Multi-Mod Manager v1.1-release_candidate1.hotfix1
Release: 10.10.2015 | Last Update: 21.01.2016

Contents' Table

Basic differences between the original Joropito's MultiMod and addons_zz's Multi-Mod Manager

addons_zz's Multi-Mod Manager can:
  1. display colored text messages.
  2. easily implemented any new feature that you want, as it is a fully documented plugin.
  3. improve its code as it is well software engineered.
  4. easily manage extremely big mod plugins files and mods configurations files.
  5. easily manage extremely big mods amount.
  6. to have unlimited MODS installed.
  7. install the fully compatible "multimod_daily_changer" provided here.
  8. install the fully compatible and new "Galileo" provided here.
  9. unload metamod csdm modules automatically after disable the csdm mod, or before enable any another mod, as long as you configure it.
  10. restore server's cvars and server's commands automatically after disable any mod, or before enable another mod, as long as you configure it.
  11. install/use every mod that exists and will exists in the universe, without any special plugin or any "Multi-Mod Manager" modification,
    as long as this mod you wanna install runs at an AMXX very own default install.
  12. if you want to, you can have any mod activated never ever at you server, even if there is more then 10 installed and fully working mods.
  13. use the command "amx_setmod help 1" display the acceptable inputs and loaded mods
    from the file "yourgamemod/addons/amxmodx/configs/multimod/voting_list.ini".
  14. automatically execute late configuration file execution to built-in AMXX per map configurations.
  15. automatically to restaure the first mapcycle used.
  16. freeze the game and show the scoreboard when activating a mod silently, using the command "amx_setmods".
  17. use the command 'amx_setmod modShortName <1 or 0>', to enable the mod "modShortName" as csdm,
    starting a vote map (1) or not (0), right after. This command can only active mods loaded from
    "voting_list.ini" file, and needs an admin level ADMIN_CFG.
  18. use the command 'amx_setmods modShortName <1 or 0>', to enable the mod "modShortName" as surf,
    restarting (1) or not (0) the server immediately, silently. This command can active any mod installed at the server
    despite it is or it is not at the "voting_list.ini" server configuration file. And most important, it needs an admin level ADMIN_IMMUNITY.
  19. use the cvar amx_multimod_endmapvote <0 - 1> to enable (1) or disable (0) end map automatic multi-mod voting.
  20. waits as long as you want to choose to activate one mod or not, by vote menu and by command line.
  21. at voting keep the current mod, if less than 30% voted, or keep it disabled if there is no mod enabled.
  22. see the voting results details at server's console.
  23. keep the server's current mod at voting as the vote menu's first option is always: "1. Keep Current Mod".
  24. disable the server's current mod at voting as the vote menu's second option is always: "2. No mod - Disable Mod".
  25. see that are any mod currently activated, when you type "say currentmod" and there is no mod active.
  26. execute a special server's configuration file at the comment you active a server's mod. That is executed only and only at the
    mod first activation time by the command "amx_setmod" (the silence one, "amx_setmods" has not this feature, because it is silent).
  27. receive a clear and self-explanatory error message when you mis-configure the mod plugins file name/location.
  28. server's admins with right flag can change the server's current mod without needing direct access like ftp, to the server's files.

See its current development at: Github
http://i.imgur.com/TWUBJiH.png
https://github.com/addonszz/MultiMod_Manager

(look for the developer and feature branches)

The original plugin "multimod.sma" is originally written by JoRoPiTo. This "Multi-Mod Manager" works
differently from the original "MultiMod Manager". See Credits for information.

This is a release candidate, which is a beta version with potential to be a final product, which is ready to be
released unless significant bugs emerge. In this stage of product stabilization, all product features have been
designed, coded and tested through one or more beta cycles with no known show stopper-class bug.

This plugin is not compatible with the AMXX's very own Map Chooser or "Daily Maps", but yes with its
modification "multimod_daily_changer" provided here. The new Galileo
which is a different Galileo version, is ready to be used with this Multi-Mod Manager".

The "Multi-Mod Daily Maps" is a modified version of "Daily Maps" to work with this "Multi-Mod Manager".
This plugin only works with "Multi-Mod Manager", alone the "Multi-Mod Daily Maps" does nothing. Its allows
you to specify a different "mapcycles" and "server cfg" files rotation, for every day. These daily mapcycles are
only active when you are not using any mod, or your current mod does not specifies a special mapcycle. The
"mapcycles" and "server cfg" files respectively, are located at "yourgamemod/mapcycles/day" and
"yourgamemod/mapcycles/day/cfg".

Click here to see all servers using this plugin.



********************** Introduction Go Top *******************************
This is a multi-mod server manager, that controls which mod is, or will be activated.
A mod can be activated by vote (say votemod), or by force (amx_setmod or amx_setmods).

There is a list of mods (voting_list.ini) that decides which mods will show up at a mod vote.
The vote mod supports a multi-page menu, that display unlimited Mods loaded from “voting_list.ini” file.

http://addons.zz.mu/recursos/2015-08...ter-Strike.jpg

The "multimod_manager.sma" waits the user choose to activate one mod, by vote menu,
or by command line. It saves the current active mod and keep it active forever or until some
other mod is activated or your disable the active mod by the "amx_setmod disable 1" command.

Features' list:
Quote:

* Changes the default mapcycle, if and only if a custom mod mapcycle was created.

* The vote menu's first to options always are: "1. Keep Current Mod" and "2. No mod - Disable Mod".

* The vote mod keep the current mod, when less than 30% of players voted.

* When the min vote mod time is not reached/disabled, display a message informing it.

* Command 'amx_votemod', to start force start a vote mod, even if it is disabled. This command can
only active mods loaded from "voting_list.ini" file, and needs an admin level ADMIN_MAP.

* Command 'amx_setmod modShortName <1 or 0>', to enable the mod "modShortName" as csdm,
starting a vote map (1) or not (0), right after. This command can only active mods loaded from
"voting_list.ini" file, and needs an admin level ADMIN_CFG.

* Command 'amx_setmods modShortName <1 or 0>', to enable the mod "modShortName" as surf,
restarting (1) or not (0) the server immediately, silently. This command can active any mod installed
at the server
despite it is or not at the "voting_list.ini" server's configuration file. And most important,
it needs an admin level ADMIN_IMMUNITY.

OBS: A mod can only to be/get activated after a restart.
The command "amx_setmod help 1" display the acceptable inputs and loaded mods
from the file "yourgamemod/addons/amxmodx/configs/multimod/voting_list.ini". There is
2 built-in operations beyond mods activation: "amx_setmod help 1" and "amx_setmod disable 1",
respectively to shows help and disable any active mod.

http://addons.zz.mu/recursos/2015-08...-Strike(2).jpg

If enabled (default disabled), when remaining 5 minutes to end current map, this plugins launches a vote to
choose which mod will be played at the next map. If less than 30% voted, the game keep the current mod
or keep it disabled if there is no mod enabled.

Example of "amx_setmod help 1":
Code:

amx_setmod help 1                | To show this help.
amx_setmod disable 1            | To deactivate any active Mod.
amx_votemod                      | To force a votemod.
say_team nextmod                | To see which is the next mod.
say currentmod                  | To see which is the current mod.
say votemod                      | To try start a vote mod.
say_team votemod                | To try start a vote mod.
amx_setmod csdm 1                | to use CS-DM (DeathMatch)
amx_setmod catch 1              | to use Catch Mod
amx_setmod dragon 1              | to use Dragon Ball Mod
amx_setmod gungame 1            | to use Gun Game Mod
amx_setmod hiden 1              | to use Hide N Seek Mod
amx_setmod jctf 1                | to use Just Capture The Flag
amx_setmod knife 1              | to use Knife Arena Mod
amx_setmod predator 1            | to use Predator Mod_b2
amx_setmod shero 1              | to use Super Heros
amx_setmod surf 1                | to use Surf Mod
amx_setmod warcraft 1            | to use Warcraft Ultimate Mod 3
amx_setmod zp50Money 1          | to use Zombie Mod with Money
amx_setmod zp50Ammo 1            | to use Zombie Mod with AmmoPacks
amx_setmod ttt 1                | to use Trouble in Terrorist Town
amx_setmod deathrun 1            | to use Deathrun Mod

********************** Requirements and Commands Go Top ******
Amx Mod X 1.8.2 or higher only

Cvars:
Quote:

// Minimum time to play before players can make MOD voting.
amx_mintime 10

// enable (1) or disable (0) end map automatic multi-mod voting.
amx_multimod_endmapvote 0

// enable (1) or disable (0) multi-mod voting (say votemod).
amx_multimod_voteallowed 1
Commands:
Quote:

//Command line control of multimod system
amx_setmod
amx_setmods

//Admin only command to launch MOD voting
amx_votemod

//Check which MOD will be running in next map
say nextmod
say_team nextmod

//Check which MOD is running in the current map
say currentmod
say_team currentmod

//Player command to launch MOD voting
say votemod
say_team votemod
There is a Multi-Mod Server Configuration with:
  • CS-DM (DeathMatch)
  • Catch Mod
  • Dragon Ball Mod
  • Gun Game Mod
  • Hide N Seek Mod
  • Just Capture The Flag
  • Knife Arena Mod
  • Predator Mod_b2
  • Super Heros
  • Surf Mod
  • Warcraft Ultimate Mod 3
  • Zombie Money Mod
  • Zombie Pack Ammo Mod
Is available here.

******************************** Installation Go Top **********************
1. Download the files "multimod_manager.sma", "configuration_files.zip",
"galileo.sma" and "multimod_daily_changer.sma"(this is optional), at Downloads section.

2. Then take the contents of "yourgamemod" from "configuration_files.zip", to your gamemod folder.

3. Compile the files and put the compiled files to your plugins folder at
"yourgamemod/addons/amxmodx/plugins" folder.

4. Put the next lines to your "plugins.ini" file at "yourgamemod/addons/amxmodx/configs" and
disable the original "mapchooser.amxx":
Quote:

multimod_manager.amxx
multimod_daily_changer.amxx
; Choose
galileo.amxx
5. Put the next line to your "amxx.cfg" file at "yourgamemod/addons/amxmodx/configs":
Quote:

exec addons/amxmodx/configs/multimod/multimod.cfg
6. Configure your own mods at "yourgamemod/addons/amxmodx/configs/multimod/voting_list.ini"
file as follow (the short mod name cannot be longer than 15 characters neither have spaces):

--- Example of: yourgamemod/addons/amxmodx/configs/multimod/voting_list.ini ------
Quote:

[Gun Game]:[gungame]:

;[mode name]:[shortModName]:
-------------- And you have to create the files:----------------------------
Quote:

yourgamemod/addons/amxmodx/configs/multimod/plugins/gungame.ini

(Optinal files)
yourgamemod/addons/amxmodx/configs/multimod/cfg/gungame.cfg
yourgamemod/addons/amxmodx/configs/multimod/latecfg/gungame.cfg
yourgamemod/addons/amxmodx/configs/multimod/msg/gungame.cfg
yourgamemod/mapcycles/gungame.txt
-------------- Explanations Go Top -------------------------

1. The file "yourgamemod/addons/amxmodx/configs/multimod/plugins/gungame.ini",
contains the plugins that compose the Mod like:
Quote:

gungame.amxx
2. The file (opcional) "yourgamemod/addons/amxmodx/configs/multimod/cfg/gungame.cfg",
contains yours special configuration used at the mod activation, like:
Quote:

amxx pause amx_adminmodel
sv_gravity 600
3. The file (opcional) "yourgamemod/addons/amxmodx/configs/multimod/cfg/gungame.cfg",
contains yours special configuration used after the mod deactivation, like:
Quote:

amxx unpause amx_adminmodel
sv_gravity 800
4. The file (opcional) "yourgamemod/addons/amxmodx/configs/multimod/msg/gungame.cfg" contains
commands that are executed when a mod is activated by the command line "amx_setmod".
Usually it contains a command to restart the server.
Example of "yourgamemod/addons/amxmodx/configs/multimod/msg/gungame.cfg":
Quote:

amx_execall speak ambience/ratchant
amx_tsay ocean GUN-GAME will be activated at next server restart!!!!
amx_tsay blue GUN-GAME will be activated at next server restart!!!!
amx_tsay cyan GUN-GAME will be activated at next server restart!!!!
amx_tsay ocean GUN-GAME will be activated at next server restart!!!!

//amx_countdown 5 restart
exec addons/amxmodx/configs/multimod/votingfinished.cfg
5. The file (opcional) "yourgamemod/mapcycles/gungame.txt" contains the mapcycle used when
gungame mod is active.

******************************** TODO Go Top *********************************
  • Create a new folder called cvars, to list the cvars to autosave to the latecfg file name. An give an option to autodetect the changed cvars from the './multimod/cfg' folder.
  • Create a option to automatically create a file at '.configs/maps' folder, to autoload a mod on its maps types, as deathrun on deathrun_/zm_ prefixes maps names. To do this, add at the voting_list, a last parameter specifing the map_prefix where that mod must be autoloaded.
******************************** Change Log Go Top ***********************
Code:

2015-10-10 | v1.0-release_candidate1
 * Initial release candidate.

2015-10-10 | v1.0-release_candidate1.hotfix1
 * Add exception handle when the currentmod_id.ini or currentmod_shortname.ini is not found.

2015-10-12 | v1.0-release_candidate2
 * Removed unused function get_firstmap() and variable g_nextmap.
 * Replaced unnecessary functions configMapManager and configDailyMaps.
 * Removed unnecessary MULTIMOD_MAPCHOOSER compiler constant.
 * Added to multimod_daily_changer.sma compatibility with Galileo.

2015-10-13 | v1.0-release_candidate2.hotfix1
 * Added missing format parameter at messageModActivated function.

2015-10-13 | v1.0-release_candidate2.hotfix2
 * Added missing MM_CHOOSE line at multilingual file.

2015-10-19 | v1.0-release_candidate2.hotfix3
 * Translated to english lost code variables.
 * Replaced a implemented switch by a native switch.
 * Replaced another implemented switch by a native switch.
 * Improved variables names meaningful.

2015-10-21 | v1.0-release_candidate2.hotfix4
 * Fixed mapcycle not setting when a mod was activated by command line or voting.

2015-10-25 | v1.1-alpha1
 * Added late configuration file execution to built-in AMXX per map configurations.
 * Added to restaure the first mapcycle used.
 * Improved code clearness.
 * Added path coders to every multi-generated string.
 * Added immutable strings paths as global variables.
 * Removed passing an integer value to a function by string.
 * Removed unnecessary variables like g_messageFileNames and g_pluginsFileNames.

2015-10-30 | v1.1-alpha1.hotfix1
 * Fixed the mod map cycle not changing.

2016-01-16 | v1.1-release_candidate1
 * Replaced wrong color chat system with correct one.
 * Use the actual current mod map cycle, right after a vote mod, instead the previous one.
 * Updated modification type to all GoldSrc engine games.
 * Fixed LANG_PLAYER misuse.
 * Fixed server_print overuse.
 * Fixed printing info to the client in a for loop can cause an overflow.
 * Implemented dynamic arrays, to have unlimited models.
 * Fixed bug, where was enabled to set a invalid mapcycle.

2016-01-21 | v1.1-release_candidate1.hotfix1
 * Fixed voting reset bug.

******************************** Credits Go Top *******************************
fysiks: The first to realize the idea of "multimod.sma" and various code improvements.
joropito: The idea/program developer of "multimod.sma".
crazyeffect: Colaborate with multilangual support of "multimod.sma".
dark vador 008: Time and server for testing under czero "multimod.sma".
Brad: The original Galileo developer.
Th3822: For find a error from map_nominate.
Addons zz: This plugin developer.
ConnorMcLeod: For the [Dyn Native] ColorChat v0.3.2 (04 jul 2013) functions.
JustinHoMi & JGHG: For the "Daily Maps" plugin.
HamletEagle: For some code improvements as unlimited mods number.

******************************** Source Code and Support Go Top ***
For any problems with this plugin visit this own page for support:
https://forums.alliedmods.net/showthread.php?t=273020

If you are posting because the plugin or a feature of the plugin isn't working for you, please do
all of the following, so we can more efficiently figure out what's going on:
Quote:

If you have access to your game server's console, type the following in the server console:
  • status
  • meta list
  • amxx list
  • amxx cvars
If you don't have access the your game server's console, join your server and type the
following in your game console:
  • status
  • rcon_password your_rcon_password
  • rcon meta list
  • rcon amxx list
  • rcon amxx cvars
  1. Paste here everything from the status command *except* the player list.
  2. Paste here the entire result from the meta list and amxx plugins commands.
  3. Paste here *only* the CVARs that contain "multimod_manager.amxx" in the last column
    from the amxx cvars command. They will be grouped together.

******************************** Downloads Go Top ********************
  • Old versions downloads:
    1. v1.1-alpha1.hotfix1: (multimod_manager.sma - 72 views - 66.8 KB)

  • galileo.sma

vedant007 10-14-2015 10:21

Re: Multi-Mod Manager v1.0-release_candidate2.hotfix2
 
Nice Plugin! :)

addons_zz 10-14-2015 10:25

Re: Multi-Mod Manager v1.0-release_candidate2.hotfix2
 
Quote:

Originally Posted by vedant007 (Post 2352973)
Nice Plugin! :)

Thank you. This is actually it looks harder, but is a lot easier. Now I am going to just try to
explain a more simple way to have the plugin configured.

The problem is that I develop a lot of features, but at short term you can just create a 'txt' file of the mod name plugins file at ./configs/plugins/mymod.txt

Then to active the mod just type at server console:
Quote:

amx_setmods mymod 1
And you are done. Later to disable the mod, just type:
Quote:

amx_setmod disable 1
But if you want that mod to show up at the voting, just edit the file ./configs/multimod/multimod.ini and add the line:
Quote:

[My Cool Mod]:[mymod]:
Hence, want more easier then this? Simple like that you can install gungame, csdm, zombie, catch, hide n seek, deathrun, jailbreak, ... at you server and never more have to worry about uninstall one to install another one.

fysiks 10-14-2015 19:47

Re: Multi-Mod Manager v1.0-release_candidate2.hotfix2
 
  • You should never return a string from a function. Strings should always be passed by-ref with the max characters passed as another parameter. Then, in the function, you would either format directly into that string using the size provided or use copy().
  • Don't pass an integer value to a function by putting it in a string. Just pass the integer. E.g. msgResourceActivated(). If the original source of the value is from a string like read_argv() then you should convert it to an integer before passing it to a function like primitiveFunctions().
  • If you are going to use the multilingual system to print to the server console, you should not use LANG_PLAYER; that just doesn't make sense. You should use LANG_SERVER.
  • This will only work with Counter-Strike (because of color chat) and thus your submission should not be labeled as "Modification: ALL".
  • Your code needs to be in English (this is a rule for plugin submissions).
  • You should use a switch() in configureMultimod() instead of conditionals because all three cases are mutually exclusive. The third case can be the "default" case.
  • IIRC, printing info to the client in a for loop can cause an overflow. Simply build the whole text into a single string and then send that only once. You can create multiple lines by using "^n".
  • The use of server_print() should be rare and mostly for debugging. For registered commands, it should only be used with register_srvcmd() (unless it's for debugging of course).
  • When you register a command with register_concmd(), you should only use console_print() to output information. Likewise, when you register a command with register_clcmd(), you should only use client_print(id, print_chat, ...) and client_print(id, print_console).

I'm sure there is more but I am done for now.


Quote:

Originally Posted by addons_zz (Post 2352974)
And even better, server's admins with right flag can change the server's current mod without needing direct access like ftp, to the server's files.

lol This is not special. It's just a consequence of doing this sort of thing and can be done with both Polymorph and Joropito's MultiMod (afaik).

addons_zz 10-16-2015 16:55

Re: Multi-Mod Manager v1.0-release_candidate2.hotfix2
 
Thank you for you time.

Quote:

Originally Posted by fysiks (Post 2353142)
You should never return a string from a function. Strings should always be passed by-ref with the max characters
passed as another parameter. Then, in the function, you would either format directly into that string using the size
provided or use copy().

Coming soon: mapCyclePathCoder( stringToCode, sizeof( stringToCode ) - 1, stringCoded )

Quote:

Originally Posted by fysiks (Post 2353142)
Don't pass an integer value to a function by putting it in a string. Just pass the integer. E.g. msgResourceActivated().
If the original source of the value is from a string like read_argv() then you should convert it to an integer before
passing it to a function like primitiveFunctions().

Yea, I should convert it to integer.

Quote:

Originally Posted by fysiks (Post 2353142)
If you are going to use the multilingual system to print to the server console, you should not use
LANG_PLAYER; that just doesn't make sense. You should use LANG_SERVER.[*]This will only work with Counter-Strike (because of color chat) and thus your submission
should not be labeled as "Modification: ALL".

I posted wrong, and I was misleading the LANG_PLAYER and LANG_SERVER's use.
It will be fixed. And I forgot, this will be modification ALL, but it is not currently modification ALL.
It will be correct at threads page until it is definitely modification all.

Quote:

Originally Posted by fysiks (Post 2353142)
Your code needs to be in English (this is a rule for plugin submissions).

It is just a variable (used a lot), and more 4 or 5. Despite that, all the code is 100% documented in english,
hence such thing would not be a problem, and some similar english variables names at a fully documented code, is a much way better than a zero documented code.
But, no worries, I will do a replace.

Quote:

Originally Posted by fysiks (Post 2353142)
You should use a switch() in configureMultimod() instead of conditionals because all three
cases are mutually exclusive. The third case can be the "default" case.

This was my fail, I literally implemented a switch, instead of using a switch.

Quote:

Originally Posted by fysiks (Post 2353142)
IIRC, printing info to the client in a for loop can cause an overflow. Simply build the whole text into
a single string and then send that only once. You can create multiple lines by using "^n".

It is the same problem as the AMXX very own "adminhelp.sma". I cannot build I a big string as pawn is limited.
I must limit the output number as "adminhelp.sma", receiving a page list number to show and limit
each page to show only a big string supported.

Quote:

Originally Posted by fysiks (Post 2353142)
The use of server_print() should be rare and mostly for debugging. For registered commands,
it should only be used with register_srvcmd() (unless it's for debugging of course).

I did not know this register_srvcmd(). Then now I can register a register_srvcmd to server_print, and another register_clcmd to client_print.

Quote:

Originally Posted by fysiks (Post 2353142)
I'm sure there is more but I am done for now.

Of course, there is more clever programing techniques to learn:
  1. use tries instead of g_modShortName.
  2. count better current playing player at playersPlaying.
  3. copy more efficiently a files at copyFiles and copyFiles2.
  4. print colored text more efficiently than at print_color.
  5. receive commands more efficiently than "command arg1 arg2" even a for 1 argument command.

Quote:

Originally Posted by fysiks (Post 2353142)
Quote:

Originally Posted by addons_zz (Post 2351892)
And even better, server's admins with right flag can change the server's current mod without needing direct access like ftp, to the server's files.

lol This is not special. It's just a consequence of doing this sort of thing and can be done with both Polymorph and Joropito's MultiMod (afaik).

You are absolutely right. This can be achieved with both fysiks' Polymorph and Joropito's MultiMod.
You both can update your's threads with this information. Hence sorry, I forgot to elaborate a basics diferences table.
Then this cannot be just a sort of things, it took me a lot time effort's to develop,
as its code now seen, my goal is to develop maintainable code, for example, it is completely documented.
Nowadays prefer to do adaptive maintenance modifying the system to scope with changes in the software environment.

fysiks 10-16-2015 23:21

Re: Multi-Mod Manager v1.0-release_candidate2.hotfix2
 
Quote:

Originally Posted by addons_zz (Post 2353736)
Coming soon: mapCyclePathCoder( stringToCode, sizeof( stringToCode ) - 1, stringCoded )

Use charsmx() for string instead of sizeof - 1.

Quote:

Originally Posted by addons_zz (Post 2353736)
It is just a variable (used a lot), and more 4 or 5. Despite that, all the code is 100% documented in english,
hence such thing would not be a problem, and some similar english variables names at a fully documented code, is a much way better than a zero documented code.
But, no worries, I will do a replace.

I didn't make the rules and they state everything must be in english.


Quote:

Originally Posted by addons_zz (Post 2353736)
It is the same problem as the AMXX very own "adminhelp.sma". I cannot build I a big string as pawn is limited.
I must limit the output number as "adminhelp.sma", receiving a page list number to show and limit
each page to show only a big string supported.

It might work for a small number of lines. Pawn does not have any limitation on how big you can make a string (the OS is the limitation here). However, I'm guessing there is a limit on how long of a string you can print due to the game but I'd guess it'd be hard to hit. IIRC, your string isn't going to be that long when you include all of the text in a single string.

Quote:

Originally Posted by addons_zz (Post 2353736)
I did not know this register_srvcmd(). Then now I can register a register_srvcmd to server_print, and another register_clcmd to client_print.

Maybe I was a little too definitive when I said what I said about this topic. I wouldn't always assume that (it is a rule of thumb) because there are some cases where you might need to use client_print() in a server command. It's better to understand the difference between the three different types of commands and prints that you can use: server, console, and client.

Quote:

Originally Posted by addons_zz (Post 2353736)
print colored text more efficiently than at print_color.

Not if you want it to be for all modifications. You need to either remove color chat entirely or properly compensate for non-Counter-Strike mods. I'd personally recommend the former.

Quote:

Originally Posted by addons_zz (Post 2353736)
receive commands more efficiently than "command arg1 arg2" even a for 1 argument command.

I'm not really sure what you mean here.


Quote:

Originally Posted by addons_zz (Post 2353736)
Then this cannot be just a sort of things, it took me a lot time effort's to develop,
as its code now seen, my goal is to develop maintainable code, for example, it is completely documented.

FYI, documented code doesn't make it maintainable but often maintainable code contains a reasonable amount of documentation. You still need to code it intelligently by using the proper structures and organization.

addons_zz 10-17-2015 18:57

Re: Multi-Mod Manager v1.0-release_candidate2.hotfix2
 
Quote:

Originally Posted by fysiks (Post 2353826)
Use charsmx() for string instead of sizeof - 1.

Why? Brad used it a lot (104 times) at his Galileo, to accomplish the same task.
I mean, what does you know, that he doesn't know, at the time he wrote the code.

Quote:

Originally Posted by fysiks (Post 2353826)
I didn't make the rules and they state everything must be in english.

Was just some variables well english documented, so any english reader can understand code.
This is what is supposed to mean the rule, everything must be in english, i.e., English readers
must to understand without consulting those ambiguous translators. Because if it is not english,
they should consult the translator, and translators are bad interpreters.
But of course, very well named english variables became easier to the native english readers to understand the code without
learning/consulting all the time, its documentation.
Those variables were not english because the I written the code originally at another language,
and at the translation process they were forgotten.

Quote:

Originally Posted by fysiks (Post 2353826)
It might work for a small number of lines. Pawn does not have any limitation on how big you can make a string (the OS is the limitation here). However, I'm guessing there is a limit on how long of a string you can print due to the game but I'd guess it'd be hard to hit. IIRC, your string isn't going to be that long when you include all of the text in a single string.

I must test it, then know which one is exactly, and if I found a good solution, I would do a pull request to that horrible "amx_help" command at "adminhelp.sma".

Quote:

Originally Posted by fysiks (Post 2353826)
Maybe I was a little too definitive when I said what I said about this topic. I wouldn't
always assume that (it is a rule of thumb) because there are some cases where you might
need to use client_print() in a server command. It's better to understand the difference
between the three different types of commands and prints that you can use: server, console, and client.

No way, and of course. However I just explained how I needed to use it, at that case.

Quote:

Originally Posted by fysiks (Post 2353826)
Not if you want it to be for all modifications. You need to either remove color chat entirely
or properly compensate for non-Counter-Strike mods. I'd personally recommend the former.

I will just recognize if I am at Counter-Strike or not, then use or not colored text.

Quote:

Originally Posted by fysiks (Post 2353826)
I'm not really sure what you mean here.

For example, when I register a register_concmd as:
register_concmd("amx_coolcommand", "receiveCommand", ADMIN_CFG, g_help_coolcommand )
And type "amx_coolcommand argument1", it shows help, even if the command uses only one argument.

Quote:

Originally Posted by fysiks (Post 2353826)
FYI, documented code doesn't make it maintainable but often maintainable code contains a
reasonable amount of documentation. You still need to code it intelligently by using the
proper structures and organization.

You are right. However I said, for example, which I mean, an example about what maintainable code has,
and as you said, it has documentation. I did not said: -"It is all you need to develop maintainable code".
However, thank you for this thread completeness.

fysiks 10-17-2015 23:06

Re: Multi-Mod Manager v1.0-release_candidate2.hotfix2
 
Quote:

Originally Posted by addons_zz (Post 2354106)
Why? Brad used it a lot (104 times) at his Galileo, to accomplish the same task.
I mean, what does you know, that he doesn't know, at the time he wrote the code.

It might not have existed when he started writing his plugin, I don't know when it was added. The biggest benefit of using it instead is self-documentation (Max Characters). Because strings and arrays are technically exactly the same thing in Pawn, it's good to use a version of sizeof that is specifically for strings.

It's also beneficial when you need to search for all strings that are passed by-ref because there should always be a charsmax() used in these cases. If you only had sizeof - 1, you would also get ALL uses of sizeof and not just strings.

Note that the performance remains unchanged because sizeof and charsmax are evaluated when you compile.

addons_zz 10-18-2015 11:36

Re: Multi-Mod Manager v1.0-release_candidate2.hotfix2
 
Quote:

Originally Posted by vedant007 (Post 2354356)
Easy to use will be creative for new ones..

Hopefully will still exist new ones.

Dream_Catcher 12-03-2015 00:12

Re: Multi-Mod Manager | Last Update: 30.10.2015
 
:cry: Can't configure how to change MODs and Maps. How to do that to the people playing on the server could vote (/rtv) and would get called in the start menu, select MODs, and then Maps mod which was voted. At the end of maps as well.

And is there a possibility of extending the map without changing the MOD and Maps

addons_zz 12-03-2015 11:03

Re: Multi-Mod Manager | Last Update: 30.10.2015
 
Quote:

Originally Posted by Dream_Catcher (Post 2368341)
:cry: Can't configure how to change MODs and Maps. How to do that to the people playing on the server could vote (/rtv) and would get called in the start menu, select MODs, and then Maps mod which was voted. At the end of maps as well.

And is there a possibility of extending the map without changing the MOD and Maps

First, install as described and fully read the main post, reading the maid post will answer yours questions, but here are some:

If the cvar "amx_multimod_voteallowed' is right, then just "say votemod" or if you are admin, type, "amx_setmods csdm 1" at console for example.

If the cvar "amx_multimod_endmapvote" is right, when remaining 5 minutes is to start a vote mod automatically.

If nothing happens, bring more info about your server, for example, as asked at the main post.

Update:

Quote:

Originally Posted by Dream_Catcher (Post 2368341)
And is there a possibility of extending the map without changing the MOD and Maps

Using and fully understanding, i.e., reading its main's posts of Galileo Reloaded and this Multi-Mod Manager, you are able to do that. If its still do not, no problem, bring yours questions about what you do not understand at theirs main posts.

Quote:

Originally Posted by Dream_Catcher (Post 2368341)
How to do that to the people playing on the server could vote (/rtv) and would get called in the start menu,

If you say "say votemod", people will vote at mods at "./configs/multimod/voting_list.ini"

And if galileo reloaded is installed, and its start voting command "gal_startvote -restart" is at "./configs/multimod/votefinished.cfg", the map voting will start.

Quote:

Originally Posted by Dream_Catcher (Post 2368341)
and would get called in the start menu, select MODs, and then Maps mod which was voted. At the end of maps as well.

What is this "start menu" you are talking?

And what is "select MODs, and then Maps mod which was voted"?


Observation:

"say votemod" is = "say /rtv", but it is for Mods and all enabled/available mods will be displayed as options.

addons_zz 01-17-2016 01:05

Re: Multi-Mod Manager | Last Update: 15.01.2016
 
Released a newer version!
Quote:

2016-01-16 | v1.1-Release_Candidate1
* Replaced wrong color chat system with correct one.
* Use the actual current mod map cycle, right after a vote mod, instead the previous one.
* Updated modification type to all GoldSrc engine games.
* Fixed LANG_PLAYER misuse.
* Fixed server_print overuse.
* Fixed printing info to the client in a for loop can cause an overflow.
* Implemented dynamic arrays, to have unlimited models.
* Fixed bug, where was enabled to set a invalid mapcycle.

addons_zz 01-21-2016 18:27

Re: Multi-Mod Manager v1.1-release-candidate1 | Last Update: 16.01.2016
 
2016-01-21 | v1.1-release_candidate1.hotfix1
* Fixed voting reset bug.

hoainam123 07-23-2016 04:31

Re: Multi-Mod Manager v1.1-release_candidate1.hotfix1 | Last Update: 21.01.2016
 
so... if i say "votemod" then the mod vote comes up?
nice plugin, but ZZ, i want say "rtv" then mod vote comes up and after choosed a mod, maps of the mod which voted comes up.

sorry for my bad english :)

hoainam123 07-23-2016 05:01

Re: Multi-Mod Manager v1.1-release_candidate1.hotfix1 | Last Update: 21.01.2016
 
hey, i think i got problem. when i say "votemod" in game it doesn't come up mod vote to choose, it says :
"Voting next mod finished....next mod will be : ..."

Although i haven't choose any mod, until i type "amx_votemod" in console.

How to fix this ?

hoainam123 07-23-2016 07:31

Re: Multi-Mod Manager v1.1-release_candidate1.hotfix1 | Last Update: 21.01.2016
 
cool ! I know what cause the problem and already fixed it

I added "rtv" by myself and now if any player want vote mod, they just need say "rtv" :)

OutSider03 01-19-2018 02:53

Re: Multi-Mod Manager v1.1-release_candidate1.hotfix1 | Last Update: 21.01.2016
 
Where I need to put the mapcycle files for each mod and for the normal mod ?
Additionally how can I schedule a mod to start an 22.00 and the normal one at 10.00 ?
With task_scheduler isn't working:
Code:

// Gungame
amx_task 22:01 "mapcyclefile gungamemapcyclefile.txt" tr
amx_task 22:00 "amx_setmod gungame 1" tr
amx_task 22:00 "amxx pause vip_fioriginal.amxx" tr
amx_task 22:00 "amxx pause lastmanbets.amxx" tr
amx_task 22:00 "amx_map gg_fest" tr
amx_task 21:55 "amx_tsay blue Modul de Gungame se activeaza in 5 minute!" tr
amx_task 21:50 "amx_tsay blue Modul de Gungame se activeaza in 10 minute" tr
amx_task 21:30 "amx_tsay blue Modul de Gungame se activeaza in 30 de minute!" tr
amx_task 21:00 "amx_tsay blue Modul de Gungame se activeaza intr-o ora!" tr

//Normal
amx_task 10:01 "mapcyclefile mapcyclefile.txt" tr
amx_task 10:00 "amx_setmod disable 1" tr
amx_task 10:00 "amxx unpause vip_fioriginal.amxx" tr
amx_task 10:00 "amxx unpause lastmanbets.amxx" tr
amx_task 10:00 "amx_map fy_snow" tr
amx_task 9:55 "amx_tsay blue Modul de Normal se activeaza in 5 minute!" tr
amx_task 9:50 "amx_tsay blue Modul de Normal se activeaza in 10 minute" tr
amx_task 9:30 "amx_tsay blue Modul de Normal se activeaza in 30 de minute!" tr
amx_task 9:00 "amx_tsay blue Modul de Normal se activeaza intr-o ora!" tr


ajpr 09-05-2018 11:47

Re: Multi-Mod Manager v1.1-release_candidate1.hotfix1 | Last Update: 21.01.2016
 
Hello, I have a problem with my mods, but I can not find a way to install them on my server.

addons_zz 09-05-2018 12:49

Re: Multi-Mod Manager v1.1-release_candidate1.hotfix1 | Last Update: 21.01.2016
 
Just read the instructions at the first page: https://forums.alliedmods.net/showth...0#Installation

Rivotril 03-15-2019 06:01

Re: Multi-Mod Manager v1.1-release_candidate1.hotfix1 | Last Update: 21.01.2016
 
Hello there, is the mod still beign updated?

Having 6 mods causes a problem with the votemod menu, with 6 mods the vote is completly invisible, with 6 mods and the #define MENU_ITEMS_PER_PAGE set to 7 the vote is shown but not the last option

addons_zz 03-15-2019 21:12

Re: Multi-Mod Manager v1.1-release_candidate1.hotfix1 | Last Update: 21.01.2016
 
I just started a local server with this and it is working fine with more than 6 mods:

https://i.imgur.com/fGe5p59.gif

I also deleted my other mods and let the server only with 7 mods, and it was file too.

Can you backup your files and try installing my multimod server (the one from the gif just above)?
Link: https://forums.alliedmods.net/showthread.php?t=273018

addons_zz 03-16-2019 16:09

Re: Multi-Mod Manager v1.1-release_candidate1.hotfix1 | Last Update: 21.01.2016
 
Quote:

Hey there, i need some help with your Multi-Mod plugin, if the mod menu needs to create a new list doesn't work, every mod is invisible for some reason
Your voting menu settings file should look like this:
"Half-Life/czero/addons/amxmodx/configs/multimod/voting_list.ini"
Code:

[CS-DM (DeathMatch)]:[csdm]:
;[Mode Name]:[shortModName]:

If you want to disable some mod, you just need to add a semicolon (;) in front of it.

On the above example, it has one mod enabled and one mode disabled.

As reference, you can look into the configurations of my multimod server:
https://forums.alliedmods.net/showthread.php?t=273018

And read carefully the instructions on the first page:
https://forums.alliedmods.net/showth...0#Installation

Quote:

and how can i remove the option of disable the current mod?
For that, you will need to edit the plugin code. But first, enable the debug mode changing this line to 1:
Code:
File: MultiModServer/plugins/addons/amxmodx/scripting/multimod_manager.sma 28: /** This is to view internal program data while execution. See the function 'debugMesssageLogger(...)' 29:  * and the variable 'g_debug_level' for more information. Default value: 0  - which is disabled. 30:  */ 31: #define IS_DEBUG_ENABLED 0

And this other line to 127:
Code:
File: MultiModServer/plugins/addons/amxmodx/scripting/multimod_manager.sma 36: /** 37:  * ( 00000 ) 0 disabled all debug. 38:  * ( 00001 ) 1 displays basic debug messages. 39:  * ( 00010 ) 2 displays each mod loaded. 40:  * ( 00100 ) 4 displays the keys pressed/mods loaded during voting. 41:  * ( 01000 ) 8 displays the the mapcycle configuration. 42:  * 43:  * ( 100.. ) 64 displays messages related 'client_print_color_internal'. 44:  * ( 1001111 ) 79 displays all debug levels. 45:  */ 46: new g_debug_level = 79

Then, you can try changing these lines:
Code:

/**
 * Makes at votemod menu, display the first mod as the option: "Keep Current Mod". And at
 * votemod menu, display the second mod as the option: "No mod - Disable Mod".
 */
public build_first_mods()
{
    g_modCounter = g_modCounter + 2

    ArrayPushString( g_mod_names, "Silent Mod Currently" )
    ArrayPushString( g_mod_shortNames, "silentMod" )

    ArrayPushString( g_mod_names, "Extend Current Mod" )
    ArrayPushString( g_mod_shortNames, "extendCurrent" )

    ArrayPushString( g_mod_names, "Disable Current Mod" )
    ArrayPushString( g_mod_shortNames, "disableMod" )
}

To:
Code:

/**
 * Makes at votemod menu, display the first mod as the option: "Keep Current Mod". And at
 * votemod menu, display the second mod as the option: "No mod - Disable Mod".
 */
public build_first_mods()
{
    g_modCounter = g_modCounter + 1

    ArrayPushString( g_mod_names, "Extend Current Mod" )
    ArrayPushString( g_mod_shortNames, "extendCurrent" )

    ArrayPushString( g_mod_names, "Disable Current Mod" )
    ArrayPushString( g_mod_shortNames, "disableMod" )
}

I think you will also need to look into the code of the menu selection, and fix the selection options, otherwise when someone selects the option 3, it will actually select the option 4.

Rivotril 03-30-2019 06:28

Re: Multi-Mod Manager v1.1-release_candidate1.hotfix1 | Last Update: 21.01.2016
 
Hello, a friend of mine fixed it for me, i don't know what the problem was but he touched the code a bit and got it

addons_zz 03-30-2019 14:14

Re: Multi-Mod Manager v1.1-release_candidate1.hotfix1 | Last Update: 21.01.2016
 
Hi,

I am curious about what the problem was. Can you share the new code, so I can compare it?

This was the first big plugin had written. Did your friend like the code?

Rivotril 03-30-2019 16:07

Re: Multi-Mod Manager v1.1-release_candidate1.hotfix1 | Last Update: 21.01.2016
 
Sure, i'll PM you it, i have a new issue now, when the players vote to extend the current mod the galileo attemps to send a vote and doesn't work as the default mapcycle doesn't have maps in it, if it did, it would only show the default mapcycle maps instead of the mod mapcycle, any idea how to fix that?

addons_zz 03-30-2019 17:34

Re: Multi-Mod Manager v1.1-release_candidate1.hotfix1 | Last Update: 21.01.2016
 
For that, can you enable the Galileo logs, this plugin logs, the condebug log and PM me the `qconsole.log` file?

To enable this plugin logs, you will need to edit the plugin code changing this line from 0 to 1:
Code:
File: amxmodx/scripting/multimod_manager.sma 28: /** This is to view internal program data while execution. See the function 'debugMesssageLogger(...)' 29:  * and the variable 'g_debug_level' for more information. Default value: 0  - which is disabled. 30:  */ 31: #define IS_DEBUG_ENABLED 0

And this other line, change the varialbe `g_debug_level` from whatever it is now to 127:
Code:
File: amxmodx/scripting/multimod_manager.sma 36: /** 37:  * ( 00000 ) 0 disabled all debug. 38:  * ( 00001 ) 1 displays basic debug messages. 39:  * ( 00010 ) 2 displays each mod loaded. 40:  * ( 00100 ) 4 displays the keys pressed/mods loaded during voting. 41:  * ( 01000 ) 8 displays the the mapcycle configuration. 42:  * 43:  * ( 100.. ) 64 displays messages related 'client_print_color_internal'. 44:  * ( 1001111 ) 79 displays all debug levels. 45:  */ 46: new g_debug_level = 127

Then, to enable the Galileo logging, editing the `galileo.sma` changing the `DEBUG_LEVEL` variable. You need to set the DEBUG_LEVEL to 16, instead of the level 0 as default. Go to around the 'line 87' and find:
Code:
#define DEBUG_LEVEL 0
and change it to:
Code:
#define DEBUG_LEVEL 16

To enable the condebug log, you can see how on the Galileo main thread support section: https://forums.alliedmods.net/showth...273019#Support

Then, you can recompile the Galileo and Multimod plugin, install their .amxx files, open your server, and run it until you reproduce the problem. On you do that, you can PM me the `qconsole.log` file.

Rivotril 03-31-2019 07:41

Re: Multi-Mod Manager v1.1-release_candidate1.hotfix1 | Last Update: 21.01.2016
 
Im using the original galileo, it basicly everytime the option of extend map is selected is using the normal mapcycle instead of the mapcycle of the current mod

addons_zz 03-31-2019 14:15

Re: Multi-Mod Manager v1.1-release_candidate1.hotfix1 | Last Update: 21.01.2016
 
Quote:

Originally Posted by Rivotril (Post 2645677)
Im using the original galileo, it basicly everytime the option of extend map is selected is using the normal mapcycle instead of the mapcycle of the current mod

Even the original galileo has a debug mode. You can try to enable it.

Then, I would say it is a bug on the original Galileo, which is not getting the correct map cycle.

There is a reason why I created a new version of Galileo, it has bugs.

I still did not receive your code from the last bug your friend fixed.

You can use https://pastebin.com/ or send an email. If you feel like not sharing because I would steal your code, it would be just sad for me because you are derivating it from an open-sourced code and are hiding bug fixes for yourself instead of sharing it with others. Anyways, why are you asking for free help here, if you do not share it? After this, I am just not sure anymore, why I would help you with my free time.

For me, I cannot say care much because if I had this problem on my server, I would definitely be able to fix. Although I am not running any servers 24/7, but others like you are may be running or trying to at least.

Rivotril 04-01-2019 10:41

Re: Multi-Mod Manager v1.1-release_candidate1.hotfix1 | Last Update: 21.01.2016
 
Quote:

Originally Posted by addons_zz (Post 2645719)
Even the original galileo has a debug mode. You can try to enable it.

Then, I would say it is a bug on the original Galileo, which is not getting the correct map cycle.

There is a reason why I created a new version of Galileo, it has bugs.

I still did not receive your code from the last bug your friend fixed.

You can use https://pastebin.com/ or send an email. If you feel like not sharing because I would steal your code, it would be just sad for me because you are derivating it from an open-sourced code and are hiding bug fixes for yourself instead of sharing it with others. Anyways, why are you asking for free help here, if you do not share it? After this, I am just not sure anymore, why I would help you with my free time.

For me, I cannot say care much because if I had this problem on my server, I would definitely be able to fix. Although I am not running any servers 24/7, but others like you are may be running or trying to at least.

Sorry, i was bussy and i needed to clear it with my friend, here's the code, i changed the close, back, next, etc. to spanish, the rest is my friend,

PHP Code:

/*********************** Licensing *******************************************************
*
*   Copyleft 2015-2016 @ Addons zz
*
*   Plugin Thread: https://forums.alliedmods.net/showthread.php?t=273020
*
*  This program is free software; you can redistribute it and/or modify it
*  under the terms of the GNU General Public License as published by the
*  Free Software Foundation; either version 2 of the License, or ( at
*  your option ) any later version.
*
*  This program is distributed in the hope that it will be useful, but
*  WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
*  General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*
***************************************************************************************
*/

#define VERSION "1.1-rc1.1"

#include <amxmodx>
#include <amxmisc>

#define LONG_STRING   256
#define COLOR_MESSAGE 192
#define SHORT_STRING  64

/** This is to view internal program data while execution. See the function 'debugMesssageLogger(...)'
 * and the variable 'g_debug_level' for more information.
 * Default value: 0  - which is disabled.
 */
#define IS_DEBUG_ENABLED 0

#if IS_DEBUG_ENABLED > 0
    #define DEBUG_LOGGER(%1) debugMesssageLogger( %1 )

/**
 * ( 00000 ) 0 disabled all debug.
 * ( 00001 ) 1 displays basic debug messages.
 * ( 00010 ) 2 displays each mod loaded.
 * ( 00100 ) 4 displays the keys pressed/mods loaded during voting.
 * ( 01000 ) 8 displays the the mapcycle configuration.
 *
 * ( ... ) 64 displays messages related 'client_print_color_internal'.
 * ( 1001111 ) 79 displays all debug levels.
 */
new g_debug_level 79

/**
 * Write debug messages to server's console accordantly to the global variable g_debug_level.
 *
 * @param mode the debug mode level, see the variable 'g_debug_level' for the levels.
 * @param message[] the text formatting rules to display.
 * @param any the variable number of formatting parameters.
 */
stock debugMesssageLoggermodemessage[], any: ... )
{
    if( 
mode g_debug_level )
    {
        static 
formated_messageLONG_STRING ]
        
        
vformatformated_messagecharsmaxformated_message ), message)
        
        
server_print"%s"formated_message         )
    }
}
#else
    #define DEBUG_LOGGER(%1) //
#endif

#define PLUGIN "Multi-Mod Manager"
#define AUTHOR "Addons zz"

#define TASK_VOTEMOD      2487002
#define TASK_CHVOMOD      2487004
#define TASKIS_PRINT_HELP 648215

/**
 * The client console lines number to print when is showed the help command.
 */
#define LINES_PER_PAGE 10

#define MENU_ITEMS_PER_PAGE 7

/**
 * Convert colored strings codes '!g for green', '!y for yellow', '!t for team'.
 */
#define INSERT_COLOR_TAGS(%1) \
    
{ \
        
replace_all( %1charsmax( %), "!g""^4" ); \
        
replace_all( %1charsmax( %), "!t""^3" ); \
        
replace_all( %1charsmax( %), "!n""^1" ); \
        
replace_all( %1charsmax( %), "!y""^1" ); \
    }

#define REMOVE_COLOR_TAGS(%1) \
    
{ \
        
replace_all( %1charsmax( %), "^1""" ); \
        
replace_all( %1charsmax( %), "^2""" ); \
        
replace_all( %1charsmax( %), "^3""" ); \
        
replace_all( %1charsmax( %), "^4""" ); \
    }

#define PRINT_COLORED_MESSAGE(%1,%2) \
    
{ \
        
message_beginMSG_ONE_UNRELIABLEg_user_msgid_, %); \
        
write_byte( %); \
        
write_string( %); \
        
message_end(); \
    }

new 
bool:g_is_color_chat_supported

new g_user_msgid
new g_coloredmenus
new g_menu_total_pages
new g_currentMod_id
new g_mapManagerType
new g_isFirstTime_serverLoad
new g_dynamic_array_size_temp

new Array:g_mod_names
new Array:g_mod_shortNames
new Array:g_votemodcount

new g_mod_name_temp      SHORT_STRING ]
new 
g_mod_short_name_tempSHORT_STRING ]

new 
g_modCounter             0
new g_isTimeTo_changeMapcyle false
new g_menuname[]             = "VOTE MOD MENU"

new g_menuPosition        33 ]
new 
g_currentMod_shortNameSHORT_STRING ]
new 
g_current_print_page  33 ]

new 
g_configFolder                 LONG_STRING ]
new 
g_masterConfig_filePath        LONG_STRING ]
new 
g_masterPlugin_filePath        LONG_STRING ]
new 
g_votingFinished_filePath      LONG_STRING ]
new 
g_currentMod_id_filePath       LONG_STRING ]
new 
g_currentMod_shortName_filePathLONG_STRING ]
new 
g_votingList_filePath          LONG_STRING ]

new 
gp_allowedvote
new gp_endmapvote
new gp_mintime
new gp_timelimit
new gp_mapcyclefile

new g_alertMultiMod512 ] = ";Configuration files of Multi-Mod System^n//\
which is run every time the server starts and defines which mods are enabled.^n//\
This file is managed automatically by multimod_manager.sma plugin^n//\
and any modification will be discarded in the activation of some mod.^n^n"

new g_helpamx_setmodSHORT_STRING ] = "help 1  | for help."
new g_helpamx_setmods128 ]         = "shortModName <1 or 0> to restart or not  \
| Enable/Disable any mod, loaded or not ( silent mod ). "

new g_cmdsAvailables[][ 72 ] =
{
    
"^namx_setmod help 1                | To show this help.",
    
"amx_setmod disable 1             | To deactivate any active Mod.",
    
"amx_votemod                      | To force a votemod.",
    
"say_team nextmod                 | To see which is the next mod.",
    
"say currentmod                   | To see which is the current mod.",
    
"say votemod                      | To try start a vote mod.",
    
"say_team votemod                 | To try start a vote mod."
}

/**
 * Register plugin commands and load configurations.
 */
public plugin_init()
{
    
register_pluginPLUGINVERSIONAUTHOR )
    
    
register_cvar"MultiModManager"VERSIONFCVAR_SERVER FCVAR_SPONLY )
    
    
register_dictionary_colored"multimodmanager.txt" )
    
    
gp_mintime     register_cvar"amx_mintime""10" )
    
gp_allowedvote register_cvar"amx_multimod_voteallowed""1" )
    
gp_endmapvote  register_cvar"amx_multimod_endmapvote""0" )
    
    
g_mod_names      ArrayCreateSHORT_STRING )
    
g_mod_shortNames ArrayCreateSHORT_STRING )
    
g_votemodcount   ArrayCreate)
    
    
register_clcmd"amx_votemod""start_vote"ADMIN_MAP"Vote for the next mod" )
    
register_clcmd"say currentmod""user_currentmod" )
    
register_clcmd"say_team currentmod""user_currentmod" )
    
register_clcmd"say votemod""user_votemod" )
    
register_clcmd"say_team votemod""user_votemod" )
    
    
register_concmd"amx_setmod""receiveCommand"ADMIN_CFGg_helpamx_setmod )
    
register_concmd"amx_setmods""receiveCommandSilent"ADMIN_IMMUNITYg_helpamx_setmods )
    
register_menucmdregister_menuidg_menuname ), 2047"player_vote" )
    
    
g_user_msgid   get_user_msgid"SayText" );
    
g_coloredmenus colored_menus()
}

/**
 * Makes auto configuration about mapchooser plugin, switching between multimod_mapchooser and
 * galileo.
 * Gets current game mods cvars pointer to this program global variables.
 * Adjust the localinfo variable that store the current mod loaded, reading the current mod file.
 */
public plugin_cfg()
{
    
gp_timelimit    get_cvar_pointer"mp_timelimit" )
    
gp_mapcyclefile get_cvar_pointer"mapcyclefile" )
    
    
get_configsdirg_configFoldercharsmaxg_configFolder ) )
    
    
formatexg_masterPlugin_filePathcharsmaxg_masterPlugin_filePath ),
            
"%s/plugins-multi.ini"g_configFolder )
    
    
formatexg_masterConfig_filePathcharsmaxg_masterConfig_filePath ),
            
"%s/multimod/multimod.cfg"g_configFolder )
    
    
formatexg_currentMod_id_filePathcharsmaxg_currentMod_id_filePath ),
            
"%s/multimod/currentmod_id.ini"g_configFolder )
    
    
formatexg_currentMod_shortName_filePathcharsmaxg_currentMod_shortName_filePath ),
            
"%s/multimod/currentmod_shortname.ini"g_configFolder )
    
    
formatexg_votingList_filePathcharsmaxg_votingList_filePath ),
            
"%s/multimod/voting_list.ini"g_configFolder )
    
    
formatexg_votingFinished_filePathcharsmaxg_votingFinished_filePath ),
            
"%s/multimod/votingfinished.cfg"g_configFolder )
    
    
g_is_color_chat_supported = ( is_running"czero" )
                                  || 
is_running"cstrike" ) )
    
    
switchMapManager()
    
    
build_first_mods()
    
load_votingList()
    
    
loadCurrentMod()
    
    
unloadLastActiveMod()
    
    if( 
get_pcvar_numgp_endmapvote ) )
    {
        
set_task15.0"check_task"TASK_VOTEMOD""0"b" )
    }
}

/**
 * After the first time the server loads, this function execute the late configuration file
 *   used to restaure the last active mod cvars changed and the first mapcycle used.
 *
 * This function stills detect when the mod is changed due specific maps configurations
 *   files like, "./configs/maps/plugins-zm.ini", that actives the zombie plague mod.
 *
 * In order to this works, you must configure the file "./configs/maps/prefix_zm.cfg"
 *   with the command:
 *          localinfo amx_lastmod zp50Money
 *
 * For the zombie plague mod, short mod name.
 */
public unloadLastActiveMod()
{
    new 
lastMod_shortName    SHORT_STRING ]
    new 
firstServer_Mapcycle        SHORT_STRING ]
    new 
lateConfig_filePath        LONG_STRING ]
    
    
get_localinfo"amx_lastmod"lastMod_shortNamecharsmaxlastMod_shortName ) )
    
get_localinfo"firstMapcycle_loaded"firstServer_MapcyclecharsmaxfirstServer_Mapcycle ) )
    
    if( !
equallastMod_shortNameg_currentMod_shortName )
        && 
g_isFirstTime_serverLoad != )
    {
        
lateConfig_pathCoderlastMod_shortNamelateConfig_filePathcharsmaxlateConfig_filePath ) )
        
        if( 
file_existslateConfig_filePath ) )
        {
            
print_at_console_to_all"Executing the deactivation mod configuration file ( %s )."lateConfig_filePath )
            
server_cmd"exec %s"lateConfig_filePath )
        }
        
        if( 
g_isFirstTime_serverLoad == )
        {
            
server_cmd"mapcyclefile %s"firstServer_Mapcycle )
        }
    }
}

/**
 * Process the input command "amx_setmod OPITON1 OPITON2".
 *
 * @param player_id - will hold the players id who started the command
 * @param level - will hold the access level of the command
 * @param cid - will hold the commands internal id
 *
 * @ARG1 firstCommand_lineArgument the modShortName to enable
 * @ARG2 secondCommand_lineArgument inform to start a vote map "1" or not "0"
 */
public receiveCommandplayer_idlevelcid )
{
    
//Make sure this user is an admin
    
if( !cmd_accessplayer_idlevelcid) )
    {
        return 
PLUGIN_HANDLED
    
}
    new 
firstCommand_lineArgument SHORT_STRING ]
    new 
secondCommand_lineArgumentSHORT_STRING ]
    
    
//Get the command arguments from the console
    
read_argv1firstCommand_lineArgument,   charsmaxfirstCommand_lineArgument ) )
    
read_argv2secondCommand_lineArgumentcharsmaxsecondCommand_lineArgument ) )
    
    new 
isTimeToRestart      equalsecondCommand_lineArgument"1" )
    
g_isTimeTo_changeMapcyle true
    
    
if( primitiveFunctionsplayer_idfirstCommand_lineArgumentisTimeToRestart ) )
    {
        if( 
activateMod_byShortNamefirstCommand_lineArgument )  )
        {
            
configureModIDfirstCommand_lineArgument )
            
messageModActivatedfirstCommand_lineArgumentisTimeToRestarttrue )
        }
        else
        {
            
printHelpplayer_id )
        }
    }
    
g_isTimeTo_changeMapcyle false
    
    
return PLUGIN_HANDLED
}

/**
 * Given a mod short name like "predator", set its plugin internal mod id.
 *
 * @param shortName the mod short name.
 *
 * @return true if shortName is a valid mod, false otherwise.
 */
public configureModIDshortName[] )
{
    for( new 
mod_id_number 3mod_id_number <= g_modCountermod_id_number++ )
    {
        
ArrayGetStringg_mod_shortNamesmod_id_numberg_mod_short_name_tempcharsmaxg_mod_short_name_temp ) )
        
        if( 
equalshortNameg_mod_short_name_temp ) )
        {
            
g_currentMod_id mod_id_number
            saveCurrentModBy_id
mod_id_number )
        }
    }
}

/**
 * Check the activation of the function of disableMods and help.
 *
 * @param firstCommand_lineArgument[] the first command line argument
 * @param secondCommand_lineArgument[] the second command line argument
 * @param player_id the player id
 *
 * @return true if was not asked for a primitive function, false otherwise.
 */
public primitiveFunctionsplayer_idfirstCommand_lineArgument[], isTimeToRestart )
{
    if( 
equalfirstCommand_lineArgument"disable" ) )
    {
        
disableMods()
        
        if( 
isTimeToRestart )
        {
            
msgResourceActivated"disable"isTimeToRestarttrue )
        }
        return 
false
    
}
    
    if( 
equalfirstCommand_lineArgument"help" ) )
    {
        
printHelpplayer_id )
        return 
false
    
}
    return 
true
}

/**
 * Given a player id, prints to him and at server console the help about the command
 * "amx_setmod".
 *
 * @param player_id the player id
 */
public printHelpplayer_id )
{
    static 
formatted_string[32]

    if( 
player_id )
    {
        
player_id player_id TASKIS_PRINT_HELP
        
        
new current_print_page_total      g_current_print_pageplayer_id ] * LINES_PER_PAGE
        g_current_print_page
player_id ] = g_current_print_pageplayer_id ] + 1
        
        DEBUG_LOGGER
1"current_print_page_total: %d, g_current_print_page[ player_id ]: %d", \
                
current_print_page_totalg_current_print_pageplayer_id ] )
        
        
// print the page header
        
if( !current_print_page_total )
        {
            for( new 
0sizeofg_cmdsAvailables ); i++ )
            {
                
client_printplayer_idprint_consoleg_cmdsAvailables] )
                
DEBUG_LOGGER1g_cmdsAvailables] )
            }
            
            
set_task1.0"printHelp"player_id )
            return
        }
        
        
// print the page body
        
if( current_print_page_total LINES_PER_PAGE g_modCounter )
        {
            new 
internal_current_page_limit 0
            
            
new menu_page_total_int g_modCounter LINES_PER_PAGE
            
new menu_page_total     floatroundfloatg_modCounter ) / floatLINES_PER_PAGE ), floatround_ceil )
            
            if( 
g_modCounter LINES_PER_PAGE )
            {
                
menu_page_total_int 1
                menu_page_total     
1
            
}
            
            
client_printplayer_idprint_console"^nPrinting Page: %d of %d",
                    
g_current_print_pageplayer_id ] - 1,
                    ( 
g_modCounter LINES_PER_PAGE ) ? menu_page_total_int menu_page_total )
            
            
DEBUG_LOGGER1"^nPrinting Page: %d of %d", \
                    
g_current_print_pageplayer_id ] - 1, \
                    ( 
g_modCounter LINES_PER_PAGE ) ? menu_page_total_int menu_page_total )
            
            for( new 
current_print_page_total LINES_PER_PAGE<= g_modCounteri++ )
            {
                
ArrayGetStringg_mod_namesig_mod_name_tempcharsmaxg_mod_name_temp ) )
                
ArrayGetStringg_mod_shortNamesig_mod_short_name_tempcharsmaxg_mod_short_name_temp ) )
                
                
formatexformatted_stringcharsmaxformatted_string ), "%s 1"g_mod_short_name_temp )
                
                
client_printplayer_idprint_console"amx_setmod %-22s| to use %s"formatted_string,
                        
g_mod_name_temp )
                
                
DEBUG_LOGGER1"amx_setmod %-22s| to use %s"formatted_stringg_mod_name_temp )
                
                if( 
internal_current_page_limit++ >= ( LINES_PER_PAGE )
                    && 
g_modCounter )
                {
                    
set_task0.5"printHelp"player_id TASKIS_PRINT_HELP )
                    break
                }
            }
        }
        
        
// print the page bottom
        
if( current_print_page_total g_modCounter )
        {
            
g_current_print_pageplayer_id ] = 0
        
}
    }
    else
    {
        for( new 
0sizeofg_cmdsAvailables ); i++ )
        {
            
server_printg_cmdsAvailables] )
        }
        
        for( new 
3<= g_modCounteri++ )
        {
            
ArrayGetStringg_mod_namesig_mod_name_tempcharsmaxg_mod_name_temp ) )
            
ArrayGetStringg_mod_shortNamesig_mod_short_name_tempcharsmaxg_mod_short_name_temp ) )
            
            
formatexformatted_stringcharsmaxformatted_string ), "%s 1"g_mod_short_name_temp )
            
server_print"amx_setmod %-22s| to use %s"formatted_stringg_mod_name_temp )
        }
        
        
server_print"^n" )
    }
}

#if AMXX_VERSION_NUM < 183
public client_disconnectplayer_id )
#else
public client_disconnectedplayer_id )
#endif
{
    
remove_taskplayer_id TASKIS_PRINT_HELP )
}

/**
 * Process the input command "amx_setmod OPITON1 OPITON2".
 * Straight restarting the server, ( silent mod ) and changes and configures the mapcycle if
 *   there is one
 *
 * @param player_id - will hold the players id who started the command
 * @param level - will hold the access level of the command
 * @param cid - will hold the commands internal id
 *
 * @arg firstCommand_lineArgument the modShortName to enable silently
 * @arg secondCommand_lineArgument inform to restart the current map "1" or not "0"
 */
public receiveCommandSilentplayer_idlevelcid )
{
    
//Make sure this user is an admin
    
if( !cmd_accessplayer_idlevelcid) )
    {
        return 
PLUGIN_HANDLED
    
}
    new 
firstCommand_lineArgument            SHORT_STRING ]
    new 
secondCommand_lineArgument        SHORT_STRING ]
    
    
read_argv1firstCommand_lineArgumentcharsmaxfirstCommand_lineArgument ) )
    
read_argv2secondCommand_lineArgumentcharsmaxsecondCommand_lineArgument ) )
    
    new 
isTimeToRestart      equalsecondCommand_lineArgument"1" )
    
g_isTimeTo_changeMapcyle true
    
    
if( equalfirstCommand_lineArgument"disable" ) )
    {
        
disableMods()
        
msgResourceActivated"disable"isTimeToRestartfalse )
    }
    else if( 
activateMod_byShortNamefirstCommand_lineArgument ) )
    {
        
g_currentMod_id 0
        saveCurrentModBy_id
)
        
        
saveCurrentModBy_ShortNamefirstCommand_lineArgument             )
        
messageModActivated(               firstCommand_lineArgumentisTimeToRestartfalse )
    }
    
g_isTimeTo_changeMapcyle false
    
    
return PLUGIN_HANDLED
}

/**
 * A simple instantly server restart.
 */
public restartTheServer()
{
    
server_cmd"restart" )
}

/**
 * Loads the 'currentmod_id.ini' and 'currentmod_shortname.ini', at ".configs/multimod" folder,
 *    that stores the current mod actually active and the current mod was activated by
 *    silent mode, respectively.
 *
 * If the mod_id stored at 'currentmod_id.ini' is:
 *     greater than 0, it is any mod saved.
 *        0, a silent mod is activated.
 *     -1, the mods are disabled.
 *
 * When 'currentmod_id.ini' stores 0, 'currentmod_shortname.ini' defines the current mod.
 * When 'currentmod_id.ini' stores anything that is not 0, 'currentmod_id.ini' defines the current mod.
 */
public loadCurrentMod()
{
    new 
currentModCode
    
new unused_lenghtInteger
    
    
new currentModCode_StringSHORT_STRING ]
    new 
currentMod_shortNameSHORT_STRING ]
    
    
// normal mod activation
    
if( file_existsg_currentMod_id_filePath ) )
    {
        
read_file(   g_currentMod_id_filePath0currentModCode_String,
                
charsmaxcurrentModCode_String ), unused_lenghtInteger )
        
        
currentModCode str_to_numcurrentModCode_String )
    }
    else
    {
        
currentModCode = -1
        write_file
g_currentMod_id_filePath,    "-1"     )
    }
    
    
// silent mod activation
    
if( file_existsg_currentMod_shortName_filePath ) )
    {
        
read_fileg_currentMod_shortName_filePath0currentMod_shortName,
                
charsmaxcurrentMod_shortName ), unused_lenghtInteger )
    }
    else
    {
        
currentModCode = -1
        write_file
g_currentMod_shortName_filePath"" )
    }
    
    
configureMod_byModCodecurrentModCodecurrentMod_shortName )
}

/**
 * Configure the current mod action after is being loaded from the file at map server start.
 *
 * @param currentModCode the code loaded from the current mod file. If it is:
 *            -1, there is no mod active.
 *         0, the current mod was activated by silent mode.
 *
 * @param currentMod_shortName[] the current mod short name loaded from the
 *    current mod silent file.
 */
public configureMod_byModCodecurrentModCodecurrentMod_shortName[] )
{
    
DEBUG_LOGGER1,  "^n^ncurrentModCode: %d | currentMod_shortName: %s^n", \
            
currentModCodecurrentMod_shortName )
    
    switch( 
currentModCode )
    {
        case -
1:
        {
            
g_currentMod_id 2
            
            ArrayGetString
g_mod_shortNamesg_currentMod_idg_mod_short_name_tempcharsmaxg_mod_short_name_temp ) )
            
setCurrentMod_atLocalInfog_mod_short_name_temp )
        }
        case 
0:
        {
            
g_currentMod_id 0
            setCurrentMod_atLocalInfo
currentMod_shortName )
        }
        default:
        {
            
g_currentMod_id currentModCode 2
            
            ArrayGetString
g_mod_shortNamesg_currentMod_idg_mod_short_name_tempcharsmaxg_mod_short_name_temp ) )
            
setCurrentMod_atLocalInfog_mod_short_name_temp )
        }
    }
}

/**
 * Configure the current mod action after being voted the next mod.
 *
 * @param mostVoted_modID the mod most voted during the vote mod:
 *      If 1, is to keep the current mod
 *      If 2, is to disable the current mod.
 */
public configureMod_byModIDmostVoted_modID )
{
    
g_currentMod_id mostVoted_modID
    
    
switch( mostVoted_modID )
    {
        case 
1:
        {
            
DEBUG_LOGGER1"^nAT configureMod_byModID, we are keeping the current mod" )
        }
        case 
2:
        {
            
disableMods()
        }
        default:
        {
            
saveCurrentModBy_idmostVoted_modID )
            
ArrayGetStringg_mod_shortNamesmostVoted_modIDg_mod_short_name_tempcharsmaxg_mod_short_name_temp ) )
            
activateMod_byShortNameg_mod_short_name_temp )
        }
    }
}

/**
 * Saves the last mod activated at localinfo "amx_lastmod" and sets the localinfo
 *   "amx_correntmod" and the global variable "g_currentMod_shortName" to the mod
 *   short name currently activated.
 *
 * @param currentMod_shortName the current just activated mod short name.
 */
public setCurrentMod_atLocalInfocurrentMod_shortName[] )
{
    
retrievesCurrentMod_atLocalInfo()
    
    
configureMapcyclecurrentMod_shortName )
    
    
set_localinfo"amx_lastmod"g_currentMod_shortName )
    
set_localinfo"amx_correntmod",     currentMod_shortName )
    
    
copyg_currentMod_shortNamecharsmaxg_currentMod_shortName ), currentMod_shortName )
}

/**
 * Retrieves the localinfo "amx_correntmod"  as a mod short name to the global variable
 *   "g_currentMod_shortName".
 */
public retrievesCurrentMod_atLocalInfo()
{
    
get_localinfo"amx_correntmod"g_currentMod_shortNamecharsmaxg_currentMod_shortName ) );
}

/**
 * Given a mod_id_number, salves it to file "currentmod_id.ini", at multimod folder.
 *
 * @param mod_id_number the mod id. If the mod_id_number is:
 *         greater than 2, it is any mod.
 *            2, a silent mod activated.
 *         1, the mods are disabled.
 */
saveCurrentModBy_idmod_id_number )
{
    new 
mod_idStringSHORT_STRING ]
    
    if( 
file_existsg_currentMod_id_filePath ) )
    {
        
delete_fileg_currentMod_id_filePath )
    }
    
    
formatexmod_idStringcharsmaxmod_idString ), "%d"mod_id_number )
    
    
write_fileg_currentMod_id_filePathmod_idString )
}

/**
 *  Saves the current silent mod activated to file "currentmod_shortname.ini", at multimod folder.
 *
 * @param modShortName[] the mod short name. Ex: surf.
 */
public saveCurrentModBy_ShortNamemodShortName[] )
{
    if( 
file_existsg_currentMod_shortName_filePath ) )
    {
        
delete_fileg_currentMod_shortName_filePath )
    }
    
write_fileg_currentMod_shortName_filePathmodShortName )
}

/**
 * Makes at votemod menu, display the first mod as the option: "Keep Current Mod". And at
 * votemod menu, display the second mod as the option: "No mod - Disable Mod".
 */
public build_first_mods()
{
    
g_modCounter g_modCounter 2
    
    ArrayPushString
g_mod_names"Modo Silencioso" )
    
ArrayPushStringg_mod_shortNames"silentMod" )
    
    
ArrayPushStringg_mod_names"Extender Modo" )
    
ArrayPushStringg_mod_shortNames"extendCurrent" )
    
    
ArrayPushStringg_mod_names"Desactivar Modo" )
    
ArrayPushStringg_mod_shortNames"disableMod" )
}

/**
 * Loads the config file "voting_list.ini" and all mods stored there.
 */
public load_votingList()
{
    new 
currentLine         LONG_STRING ]
    new 
currentLine_splited SHORT_STRING ]
    new 
unusedLast_string   SHORT_STRING ]
    
    new 
votingList_filePointer fopeng_votingList_filePath"rt" )
    
    while( !
feofvotingList_filePointer ) )
    {
        
fgetsvotingList_filePointercurrentLinecharsmaxcurrentLine ) )
        
trimcurrentLine )
        
        
// skip commentaries while reading file
        
if( !currentLine]
            || 
currentLine] == ';'
            
|| ( currentLine] == '/'
                 
&& currentLine] == '/' ) )
        {
            continue
        }
        
        if( 
currentLine] == '[' )
        {
            
g_modCounter++
            
            
// remove line delimiters [ and ]
            
replace_allcurrentLinecharsmaxcurrentLine ), "[""" )
            
replace_allcurrentLinecharsmaxcurrentLine ), "]""" )
            
            
// broke the current config line, in modname ( g_mod_name_temp ), modtag ( g_mod_short_name_temp )
            
strtokcurrentLineg_mod_name_tempcharsmaxg_mod_name_temp ), currentLine_splited,
                    
charsmaxcurrentLine_splited ), ':')
            
strtokcurrentLine_splitedg_mod_short_name_tempcharsmaxg_mod_short_name_temp ), unusedLast_string,
                    
charsmaxunusedLast_string ), ':')
            
            
// stores at memory the modname and the modShortName
            
ArrayPushStringg_mod_namesg_mod_name_temp )
            
ArrayPushStringg_mod_shortNamesg_mod_short_name_temp )
        
        
#if IS_DEBUG_ENABLED > 0
            
ArrayGetStringg_mod_namesg_modCounterg_mod_name_tempcharsmaxg_mod_name_temp ) )
            
DEBUG_LOGGER1"[AMX MOD Loaded] %d - %s",  g_modCounter 2g_mod_name_temp )
            
            if( 
g_debug_level )
            {
                new 
mapcycle_filePath       SHORT_STRING ]
                new 
config_filePath         SHORT_STRING ]
                new 
plugin_filePath         SHORT_STRING ]
                new 
message_filePath        SHORT_STRING ]
                new 
messageResource_filePathSHORT_STRING ]
                new 
lateConfig_filePath     SHORT_STRING ]
                
                
mapcycle_pathCoderg_mod_short_name_tempmapcycle_filePathcharsmaxmapcycle_filePath ) )
                
config_pathCoderg_mod_short_name_tempconfig_filePathcharsmaxconfig_filePath ) )
                
plugin_pathCoderg_mod_short_name_tempplugin_filePathcharsmaxplugin_filePath ) )
                
message_pathCoderg_mod_short_name_tempmessage_filePathcharsmaxmessage_filePath ) )
                
                
messageResource_pathCoderg_mod_short_name_tempmessageResource_filePath,
                        
charsmaxmessageResource_filePath ) )
                
                
lateConfig_pathCoderg_mod_short_name_templateConfig_filePathcharsmaxlateConfig_filePath ) )
                
                
DEBUG_LOGGER1"[AMX MOD Loaded] %s"g_mod_short_name_temp )
                
DEBUG_LOGGER1"[AMX MOD Loaded] %s"mapcycle_filePath )
                
DEBUG_LOGGER1"[AMX MOD Loaded] %s"plugin_filePath )
                
DEBUG_LOGGER1"[AMX MOD Loaded] %s"config_filePath )
                
DEBUG_LOGGER1"[AMX MOD Loaded] %s"message_filePath )
                
DEBUG_LOGGER1"[AMX MOD Loaded] %s"lateConfig_filePath )
                
DEBUG_LOGGER1"[AMX MOD Loaded] %s^n"messageResource_filePath )
            }
        
#endif
        
}
    }
    
fclosevotingList_filePointer )
}

/**
 * Hard code the message recourse file location at the string parameter messageResource_filePath[].
 * These are the resource messages files at ".configs/multimod/" folder. executed when a
 *   resource as disable, is activated by the command "amx_setmod".
 *
 * @param modShortName[] the mod short name without extension. Ex: surf
 * @param messageResource_filePath[] the message resource file path containing its file extension.
 *                    Ex: mapcycles/surf.txt
 *
 * @param stringReturnSize the messageResource_filePath[] charsmax value.
 */
public messageResource_pathCoderresourceName[], messageResource_filePath[], stringReturnSize )
{
    
formatexmessageResource_filePathstringReturnSize"%s/multimod/%s.cfg"g_configFolderresourceName )
}

/**
 * Hard code the message file location at the string parameter message_filePath[].
 * These are the messages files at ".configs/multimod/msg/" folder, executed when a
 *   mod is activated by the command "amx_setmod".
 *
 * @param modShortName[] the mod short name without extension. Ex: surf
 * @param message_filePath[] the message file path containing its file extension. Ex: mapcycles/surf.txt
 * @param stringReturnSize the message_filePath[] charsmax value.
 */
public message_pathCodermodShortName[], message_filePath[], stringReturnSize )
{
    
formatexmessage_filePathstringReturnSize"%s/multimod/msg/%s.cfg"g_configFoldermodShortName )
}

/**
 * Hard code the plugin file location at the string parameter plugin_filePath[].
 * These are the mods plugins files, to be activated at ".configs/multimod/plugins/" folder.
 *
 * @param modShortName[] the mod short name without extension. Ex: surf
 * @param plugin_filePath[] the plugin file path containing its file extension. Ex: mapcycles/surf.txt
 * @param stringReturnSize the plugin_filePath[] charsmax value.
 */
public plugin_pathCodermodShortName[], plugin_filePath[], stringReturnSize )
{
    
formatexplugin_filePathstringReturnSize"%s/multimod/plugins/%s.ini"g_configFoldermodShortName )
}

/**
 * Hard code the config file location at the string parameter config_filePath[].
 * These are the mods configuration files, to be loaded at ".configs/multimod/cfg/" folder.
 *
 * @param modShortName[] the mod short name without extension. Ex: surf
 * @param config_filePath[] the config file path containing its file extension. Ex: mapcycles/surf.txt
 * @param stringReturnSize the config_filePath[] charsmax value.
 */
public config_pathCodermodShortName[], config_filePath[], stringReturnSize )
{
    
formatexconfig_filePathstringReturnSize"%s/multimod/cfg/%s.cfg"g_configFoldermodShortName )
}

/**
 * Hard code the late config file location at the string parameter lateConfig_filePath[].
 * These are the mods configuration files, to be loaded at ".configs/multimod/latecfg/" folder.
 * These files are only executed once when the mod is deactivated.
 *
 * @param modShortName[] the mod short name without extension. Ex: surf
 * @param lateConfig_filePath[] the late config file path containing its file extension. Ex: mapcycles/surf.txt
 * @param stringReturnSize the lateConfig_filePath[] charsmax value.
 */
public lateConfig_pathCodermodShortName[], lateConfig_filePath[], stringReturnSize )
{
    
formatexlateConfig_filePathstringReturnSize"%s/multimod/latecfg/%s.cfg"g_configFoldermodShortName )
}

/**
 * Hard code the mapcycle file location at the string parameter mapcycle_filePath[].
 * These are the mods mapcycles files at ".gamemod/mapcycles/" folder, to be used when a mod is
 *   activated.
 *
 * @param modShortName[] the mod short name without extension. Ex: surf
 * @param mapcycle_filePath[] the mapcycle file path containing its file extension. Ex: mapcycles/surf.txt
 * @param stringReturnSize the mapcycle_filePath[] charsmax value.
 */
public mapcycle_pathCodermodShortName[], mapcycle_filePath[], stringReturnSize )
{
    
formatexmapcycle_filePathstringReturnSize"mapcycles/%s.txt"modShortName )
}

/**
 * Configure which map cycles the server will use at start up and after each mod is loaded.
 *
 * @param modShortName[] the mod short name to configure is mapcycle. Ex: csdm
 */
configureMapcyclemodShortName[] )
{
    new 
mapcycle_filePathSHORT_STRING ]
    
    
mapcycle_pathCodermodShortNamemapcycle_filePathcharsmaxmapcycle_filePath ) )
    
    
configMapManagermapcycle_filePath )
    
configDailyMapsmapcycle_filePath )
}

/**
 * Makes the autoswitch between mapchooser and galileo_reloaded. If both are
 *   active, prevails galileo_reloaded.
 */
public switchMapManager()
{
    if( 
is_plugin_loaded"Galileo" ) != -)
    {
        
g_mapManagerType 2
    
}
    else if( 
find_plugin_byfile"Nextmap Chooser" ) != -)
    {
        
g_mapManagerType 1
    
}
}

/**
 * Setup the map manager to work with votemod menu at Silent mode. That is, configures
 *  the compatibility with galileo_reloaded, multimod_mapchooser and daily_maps, because now
 *  there is no mod_id_number, hence because the mod is not loaded from the mod file configs.
 *
 * @param mapcycle_filePath[] the mapcycle file name with extension and path. Ex: mapcycles/surf.txt
 */
public configMapManagermapcycle_filePath[] )
{
    if( 
file_existsmapcycle_filePath ) )
    {
        switch( 
g_mapManagerType )
        {
            case 
1:
            {
                if( 
callfunc_begin"plugin_init""multimod_mapchooser.amxx" ) == )
                {
                    
callfunc_end()
                }
                else
                {
                    
log_errorAMX_ERR_NOTFOUND"Error at configMapManager!! multimod_mapchooser.amxx NOT FOUND!^n" )
                    
print_at_console_to_all"Error at configMapManager!! multimod_mapchooser.amxx NOT FOUND!^n" )
                }
            }
            case 
2:
            {
                new 
galileo_mapfile get_cvar_pointer"gal_vote_mapfile" )
                
                if( 
galileo_mapfile )
                {
                    
set_pcvar_stringgalileo_mapfilemapcycle_filePath )
                }
            }
        }
    }
    
    if( 
file_existsmapcycle_filePath ) )
    {
        
set_pcvar_stringgp_mapcyclefilemapcycle_filePath )
    }
    
    
server_exec()
}

/**
 * Change the game global variable at localinfo isFirstTime_serverLoad to 1 or 2, after
 *   the first map load. It is to avoid mapcycle re-change, causing the first mapcycle
 *   map, always being the nextmap.
 *
 * The localinfo isFirstTime_serverLoad as 1, is used by multimod_manager.sma,
 *    to know if there is a game mod mapcycle file being used.
 *
 * The localinfo isFirstTime_serverLoad as 2, is used by multimod_daily_changer.sma,
 *    to know if its can define which one is the mapcycle.
 *
 * @param mapcycle_filePath[] the mapcycle file name with its extension and path. Ex: mapcycles/surf.txt
 */
public configDailyMapsmapcycle_filePath[] )
{
    new 
isFirstTime32 ]
    
    
get_localinfo(       "isFirstTime_serverLoad"isFirstTimecharsmaxisFirstTime ) );
    
g_isFirstTime_serverLoad str_to_numisFirstTime )
    
    if( 
g_isFirstTime_serverLoad  == )
    {
        new 
currentMapcycle_filePathSHORT_STRING ]
        
        
g_isTimeTo_changeMapcyle true
        
        get_pcvar_string
gp_mapcyclefilecurrentMapcycle_filePathcharsmaxcurrentMapcycle_filePath ) )
        
        
set_localinfo(   "firstMapcycle_loaded",         currentMapcycle_filePath )
    }

#if IS_DEBUG_ENABLED > 0
    
DEBUG_LOGGER1"( Inside ) configDailyMaps()" )
    
DEBUG_LOGGER1"g_isFirstTime_serverLoad is: %d",         g_isFirstTime_serverLoad         )
    
DEBUG_LOGGER1"g_isTimeTo_changeMapcyle is: %d",         g_isTimeTo_changeMapcyle         )
    
DEBUG_LOGGER1"file_exists( mapcycle_filePath ) is: %d"file_existsmapcycle_filePath ) )
    
DEBUG_LOGGER1"mapcycle_filePath is: %s^n",              mapcycle_filePath                )
#endif
    
    
if( g_isTimeTo_changeMapcyle )
    {
        
g_isTimeTo_changeMapcyle false
        
        
if( file_existsmapcycle_filePath ) )
        {
            
set_pcvar_string(   gp_mapcyclefile,           mapcycle_filePath )
            
set_localinfo(  "isFirstTime_serverLoad",         "1"                 )
            
server_exec()
        }
        else
        {
            
set_localinfo"isFirstTime_serverLoad""2" );
        }
    }
}

/**
 * Deactivate any loaded/active mod.
 */
public disableMods()
{
    
DEBUG_LOGGER1"^n AT disableMods, the g_currentMod_shortName is: %s^n"g_currentMod_shortName )
    
    if( 
file_existsg_currentMod_id_filePath ) )
    {
        
delete_fileg_currentMod_id_filePath )
    }
    
    if( 
file_existsg_masterConfig_filePath ) )
    {
        
delete_fileg_masterConfig_filePath )
    }
    
    if( 
file_existsg_currentMod_shortName_filePath ) )
    {
        
delete_fileg_currentMod_shortName_filePath )
    }
    
    if( 
file_existsg_masterPlugin_filePath ) )
    {
        
delete_fileg_masterPlugin_filePath )
    }
    
    
write_fileg_masterConfig_filePath,                     g_alertMultiMod )
    
write_fileg_masterPlugin_filePath,                                     g_alertMultiMod )
    
write_fileg_currentMod_shortName_filePath,         ""                             )
    
write_fileg_currentMod_id_filePath,                         "-1"                             )
}

/**
 * Actives a mod by its short name. If the the short name plugin file exists and
 *    change the current mod to 'Keep Current Mod'.
 *
 * @param modShortName[] the mod short name to active. Ex: surf
 *
 * @throws error any configuration file is missing!
 */
public activateMod_byShortNamemodShortName[] )
{
    new 
plugin_filePathLONG_STRING ]
    
    
plugin_pathCodermodShortNameplugin_filePathcharsmaxplugin_filePath ) )
    
    if( 
file_existsplugin_filePath ) )
    {
        new 
config_filePathLONG_STRING ]
        
        
config_pathCodermodShortNameconfig_filePathcharsmaxconfig_filePath ) )
        
        if( 
file_existsconfig_filePath ) )
        {
            
copyFilesconfig_filePathg_masterConfig_filePathg_alertMultiMod )
        }
        
copyFilesplugin_filePathg_masterPlugin_filePathg_alertMultiMod )
        
        
configureMapcyclemodShortName )
        
        
print_at_console_to_all"[AMX MOD Loaded] Setting multimod to %s"modShortName )
        
        return 
true
    
}
    else
    {
        
log_errorAMX_ERR_NOTFOUND"Error at activateMod_byShortName!! plugin_filePath: %s"plugin_filePath )
        
print_at_console_to_all"Error at activateMod_byShortName!! plugin_filePath: %s"plugin_filePath )
    }
    
DEBUG_LOGGER1"^n activateMod_byShortName, plugin_filePath: %s^n"plugin_filePath )
    
    return 
false
}

/**
 * Copy the sourceFilePath to destinationFilePath, replacing the existing file destination and
 * adding to its beginning the contents of the String inicialFileText.
 *
 * @param sourceFilePath[] the source file
 * @param destinationFilePath[] the destination file
 * @param inicialFileText[] an additional text
 */
public copyFilessourceFilePath[], destinationFilePath[], inicialFileText[] )
{
    if( 
file_existsdestinationFilePath ) )
    {
        
delete_filedestinationFilePath )
    }
    
write_filedestinationFilePathinicialFileText)
    
    new 
sourceFilePathPointer fopensourceFilePath"rt" )
    new 
Text512 ];
    
    while( !
feofsourceFilePathPointer ) )
    {
        
fgetssourceFilePathPointerTextsizeofText ) - )
        
trimText )
        
write_filedestinationFilePathText, -)
    }
    
fclosesourceFilePathPointer )
}

/**
 * Copies the contents of sourceFilePath to the beginning of destinationFilePath
 *
 * @param sourceFilePath[] the source file
 * @param destinationFilePath[] the destination file
 */
public copyFiles2sourceFilePath[], destinationFilePath[] )
{
    new 
sourceFilePathPointer fopensourceFilePath"rt" )
    new 
Text512 ];
    
    while( !
feofsourceFilePathPointer ) )
    {
        
fgetssourceFilePathPointerTextsizeofText ) - )
        
trimText )
        
write_filedestinationFilePathText, -)
    }
    
fclosesourceFilePathPointer )
}

/**
 * Displays a message to all server players about a command line Mod active with "amx_setmod".
 *
 * @param modShortName[] the activated mod mod long name. Ex: surf
 * @param isTimeToRestart inform to restart the server
 * @param isTimeTo_executeMessage instruct to execute the message activation file. Ex: "msg/csdm.cfg"
 */
public messageModActivatedmodShortName[], isTimeToRestartisTimeTo_executeMessage )
{
    
client_print_color_internal0"^1The mod ( ^4%s^1 ) will be activated at ^4next server restart^1."modShortName )
    
    if( 
isTimeToRestart )
    {
        new 
message_filePathLONG_STRING ]
        
        
message_pathCodermodShortNamemessage_filePathcharsmaxmessage_filePath ) )
        
        if( 
file_existsmessage_filePath )
            && 
isTimeTo_executeMessage )
        {
            
server_cmd"exec %s"message_filePath )
        }
        else
        {
            
// freeze the game and show the scoreboard
            
message_beginMSG_ALLSVC_INTERMISSION );
            
message_end();
            
            
set_task5.0"restartTheServer" );
        }
    }
}

/**
 * Displays a message to all server player about a command line Resource active with "amx_setmod".
 * Its must match the file msg name at "multimod" folder.
 *
 * @param resourceName[] the name of the activated resource. Ex: disable
 * @param isTimeToRestart inform to restart the server
 * @param isTimeTo_executeMessage instruct to execute the message activation file. Ex: "msg/csdm.cfg"
 */
public msgResourceActivatedresourceName[], isTimeToRestartisTimeTo_executeMessage )
{
    
client_print_color_internal0"^1The resource ( ^4%s^1 ) will be activated at ^4next server restart^1."resourceName )
    
    if( 
isTimeToRestart )
    {
        new 
messageResource_filePathLONG_STRING ]
        
        
messageResource_pathCoderresourceNamemessageResource_filePathcharsmaxmessageResource_filePath ) )
        
        if( 
file_existsmessageResource_filePath )
            && 
isTimeTo_executeMessage )
        {
            
server_cmd"exec %s"messageResource_filePath )
        }
        else
        {
            
// freeze the game and show the scoreboard
            
message_beginMSG_ALLSVC_INTERMISSION );
            
message_end();
            
            
set_task5.0"restartTheServer" );
        }
    }
}

/**
 * Displays a message to a specific server player show the current mod.
 *
 * @param player_id the player id
 */
public user_currentmodplayer_id )
{
    
ArrayGetString(               g_mod_namesg_currentMod_idg_mod_name_tempcharsmaxg_mod_name_temp ) )
    
client_print_color_internalplayer_id"^1L%"player_id"MM_HUDMSG"g_mod_name_temp )
    
    return 
PLUGIN_HANDLED
}

/**
 * Called with "say votemod". Checks:
 *    If users can invoke voting.
 *    If its already voted.
 *
 * @param player_id the player id
 */
public user_votemodplayer_id )
{
    if( 
get_pcvar_numgp_allowedvote ) )
    {
        
ArrayGetString(               g_mod_namesg_currentMod_idg_mod_name_tempcharsmaxg_mod_name_temp ) )
        
client_print_color_internalplayer_id"^1%L"player_id"MM_VOTEMOD"g_mod_name_temp )
        
        return 
PLUGIN_HANDLED
    
}
    new 
Float:elapsedTime get_pcvar_floatgp_timelimit ) - ( floatget_timeleft() ) / 60.0 )
    new 
Float:minTime
    minTime 
get_pcvar_floatgp_mintime )
    
    if( 
elapsedTime minTime )
    {
        
client_print_color_internalplayer_id"^4[AMX MultiMod]^1 %L"player_id"MM_PL_WAIT",
                
floatroundminTime elapsedTimefloatround_ceil ) )
        
        return 
PLUGIN_HANDLED
    
}
    new 
timeleft get_timeleft()
    
    if( 
timeleft 180 )
    {
        
client_print_color_internalplayer_id"^1%L"player_id"MM_PL_WAIT"timeleft )
        
        return 
PLUGIN_HANDLED
    
}
    
start_vote()
    return 
PLUGIN_HANDLED
}

public 
check_task()
{
    new 
timeleft get_timeleft()
    
    if( 
timeleft 300
        
|| timeleft 330 )
    {
        return
    }
    
start_vote()
}

/**
 * Start multi mod voting.
 *
 * If a new voting was invoked:
 *   Restart voting count.
 *   Restart voting players menu position.
 */
public start_vote()
{
    
remove_taskTASK_VOTEMOD )
    
remove_taskTASK_CHVOMOD )
    
    for( new 
033i++ )
    {
        
g_menuPosition] = 0
    
}
    
    
ArrayClearg_votemodcount )
    
    for( new 
0ArraySizeg_mod_names ); i++ )
    {
        
ArrayPushCellg_votemodcount)
    }
    
    
display_votemod_menu0)
    
client_cmd0"spk Gman/Gman_Choose2" )

#if IS_DEBUG_ENABLED > 0
    
set_task6.0"check_vote"TASK_CHVOMOD )
#else
    
set_task30.0"check_vote"TASK_CHVOMOD )
#endif
}

/**
 * Create the vote mod menu multi pages.
 *
 * @param player_id the player id to display the menu.
 * @param menu_current_page the number of the current menu page to draw the menu.
 */
public display_votemod_menuplayer_idmenu_current_page )
{
    if( 
menu_current_page )
    {
        return
    }
    
    new 
menu_body1024 ]
    new 
menu_valid_keys
    
new current_write_position
    
new current_page_itens
    
new g_menusNumber g_modCounter
    
    
// calc. g_menu_total_pages
    
if( ( g_menusNumber MENU_ITEMS_PER_PAGE ) > )
    {
        
g_menu_total_pages = ( g_menusNumber MENU_ITEMS_PER_PAGE ) + 1
    
}
    else
    {
        
g_menu_total_pages = ( g_menusNumber MENU_ITEMS_PER_PAGE )
    }
    
    
// calc. Menu titles
    
if( g_coloredmenus )
    {
        
current_write_position formatexmenu_bodycharsmaxmenu_body ), "\y%L: \R%d/%d\w^n^n",
                
player_id"MM_CHOOSE"menu_current_page 1g_menu_total_pages )
    }
    else
    {
        
current_write_position formatexmenu_bodycharsmaxmenu_body ), "%L: %d/%d^n^n",
                
player_id"MM_CHOOSE"menu_current_page 1g_menu_total_pages )
    }
    
    
// calc. the number of current_page_itens
    
if( g_menu_total_pages == menu_current_page )
    {
        
current_page_itens g_menusNumber MENU_ITEMS_PER_PAGE
    
}
    else
    {
        
current_page_itens MENU_ITEMS_PER_PAGE
    
}
    
    
// calc. the current page menu body
    
new for_index 0
    
new mod_vote_id
    
    
for( new vote_mod_code menu_current_page 10;
         
vote_mod_code menu_current_page 10 current_page_itensvote_mod_code++ )
    {
        
mod_vote_id convert_octal_to_decimalvote_mod_code )
        
        
ArrayGetStringg_mod_namesmod_vote_id 1g_mod_name_tempcharsmaxg_mod_name_temp ) )
        
        
current_write_position += formatexmenu_bodycurrent_write_position ],
                
sizeofmenu_body ) - current_write_position"%d. %s^n"for_index 1g_mod_name_temp )
        
        
DEBUG_LOGGER4"( inside ) display_votemod_menu()| mod_vote_id:%d"mod_vote_id )
        
for_index++
    }
    
    
// create valid keys ( 0 to 9 )
    
menu_valid_keys MENU_KEY_0
    
    
for( new 09i++ )
    {
        
menu_valid_keys |= ( << )
    }
    
menu_valid_keys |= MENU_KEY_9
    
    
// calc. the final page buttons
    
if( menu_current_page )
    {
        if( 
g_menu_total_pages == menu_current_page )
        {
            
current_write_position += formatexmenu_bodycurrent_write_position ],
                    
sizeofmenu_body ) - current_write_position"^n0. Atrás" )
        }
        else
        {
            
current_write_position += formatexmenu_bodycurrent_write_position ],
                    
sizeofmenu_body ) - current_write_position"^n9. Más...^n0. Atrás" )
        }
    }
    else
    {
        if( 
g_menu_total_pages != menu_current_page )
        {
            
current_write_position += formatexmenu_bodycurrent_write_position ],
                    
sizeofmenu_body ) - current_write_position"^n9. Más...^n" )
        }
    }

#if IS_DEBUG_ENABLED > 0
    
new debug_player_name64 ]
    
    
get_user_nameplayer_iddebug_player_name63 )
    
    
DEBUG_LOGGER1"Player: %s^nMenu body %s ^nMenu name: %s ^nMenu valid keys: %i", \
            
debug_player_namemenu_bodyg_menunamemenu_valid_keys )
    
    
show_menuplayer_idmenu_valid_keysmenu_body5g_menuname )
#else
    
show_menuplayer_idmenu_valid_keysmenu_body25g_menuname )
#endif
}

/**
 * Given a vote_mod_code ( octal number ), calculates and return the mod internal id
 * ( decimal number ).
 */
public convert_octal_to_decimaloctal_number )
{
    new 
decimal 0
    
new i       0
    
new remainder
    
    
while( octal_number != )
    {
        
remainder     octal_number 10
        octal_number 
/= 10
        decimal      
+= remainder power8);
        ++
i
    
}
    return 
decimal;
}

/**
 * Compute a player mod vote.
 *
 * @param player_id the player id
 * @param key the player pressed/option key.
 */
public player_voteplayer_idkey )
{
    
DEBUG_LOGGER4"Key before switch: %d"key )
    
    
/* Well, I dont know why, but it doesnt even matter, how hard you try...
     * You press the key 0, you gets 9 here. ...
     * So here, i made the switch back.  */
    
switch( key )
    {
        case 
9key 0
        
case 0key 1
        
case 1key 2
        
case 2key 3
        
case 3key 4
        
case 4key 5
        
case 5key 6
        
case 6key 7
        
case 7key 8
        
case 8key 9
    
}
    
DEBUG_LOGGER4"Key after switch: %d"key )
    
    if( 
key == )
    {
        if( 
g_menuPositionplayer_id ] + != g_menu_total_pages )
        {
            
display_votemod_menuplayer_id, ++g_menuPositionplayer_id ] )
        }
        else
        {
            
display_votemod_menuplayer_idg_menuPositionplayer_id ] )
        }
    }
    else
    {
        if( 
key == )
        {
            if( 
g_menuPositionplayer_id ] != )
            {
                
display_votemod_menuplayer_id, --g_menuPositionplayer_id ] )
            }
            else
            {
                
display_votemod_menuplayer_idg_menuPositionplayer_id ] )
            }
        }
        else
        {
            new 
mod_vote_id get_mod_vote_idg_menuPositionplayer_id ], key )
            
            if( 
mod_vote_id <= g_modCounter )
            {
                new 
player_nameSHORT_STRING ]
                
                
get_user_name(  player_idplayer_namecharsmaxplayer_name ) )
                
ArrayGetStringg_mod_namesmod_vote_idg_mod_name_tempcharsmaxg_mod_name_temp ) )
                
                
client_print_color_internal0"^1%L"LANG_PLAYER"X_CHOSE_X"player_nameg_mod_name_temp )
                
DEBUG_LOGGER1"^1%L"player_id"X_CHOSE_X"player_nameg_mod_name_temp )
                
                new 
current_votes ArrayGetCellg_votemodcountmod_vote_id )
                
                
ArraySetCellg_votemodcountmod_vote_idcurrent_votes )
            }
            else
            {
                
display_votemod_menuplayer_idg_menuPositionplayer_id ] )
            }
        }
    }
}

/**
 * Given a current_menu_page and a current_pressed_key, returns internal the vote mod id.
 *
 * @param current_menu_page the current page of player vote menu.
 * @param current_pressed_key the key pressed by the player to vote.
 */
public get_mod_vote_idcurrent_menu_pagecurrent_pressed_key )
{
    new 
vote_mod_code current_menu_page 10 current_pressed_key
    
new mod_vote_id   convert_octal_to_decimalvote_mod_code )
    
    return 
mod_vote_id
}

/**
 * Start computing the mod voting.
 */
public check_vote()
{
    new 
mostVoted_modID 1
    
new totalVotes
    
    
for( new possible_most_voted_index 0possible_most_voted_index <= g_modCounter;
         
possible_most_voted_index++ )
    {
        
g_dynamic_array_size_temp ArrayGetCellg_votemodcountpossible_most_voted_index )
        
        if( 
ArrayGetCellg_votemodcountmostVoted_modID ) < g_dynamic_array_size_temp )
        {
            
mostVoted_modID possible_most_voted_index
        
}
        
        
totalVotes totalVotes g_dynamic_array_size_temp
        
        DEBUG_LOGGER
1"( inside ) check_vote()| totalVotes:%d, g_dynamic_array_size_temp: %d", \
                
totalVotesg_dynamic_array_size_temp )
    }
    
displayVoteResultsmostVoted_modIDtotalVotes )
}

/**
 * Calculates the minimum votes required and print to server users the mod voting results.
 *
 * @param mostVoted_modID the most voted mod id.
 * @param totalVotes the number total of votes.
 */
public displayVoteResultsmostVoted_modIDtotalVotes )
{
    new 
playerMin players_currently_playing0.3 )
    
    
ArrayGetStringg_mod_namesmostVoted_modIDg_mod_name_tempcharsmaxg_mod_name_temp ) )
    
    if( 
totalVotes playerMin )
    {
        
g_isTimeTo_changeMapcyle true
        
        configureMod_byModID
(       mostVoted_modID    )
        
client_print_color_internal0,  "^1%L"LANG_PLAYER"MM_VOTEMOD"g_mod_name_temp )
        
server_cmd(        "exec %s"g_votingFinished_filePath )
    }
    else
    {
        
client_print_color_internal0,  "^1The vote did not reached the ^3required minimum! \
                ^4The next mod remains: %s"
g_mod_name_temp )
    }
    
    
print_at_console_to_all"Total Mod Votes: %d  | Player Min: %d  | Most Voted: %s",
            
totalVotesplayerMing_mod_name_temp )
}

/**
 * Returns the percent of player playing at game server, skipping bots and spectators.
 *
 * @param percent a percent of the total playing players, in decimal. Example for 30%: 0.3
 *
 * @return an integer of the parameter percent of players
 */
public players_currently_playingFloat:percent )
{
    new 
players32 ]
    new 
players_count
    
new count 0
    
    
// get the players in the server skipping bots
    
get_playersplayersplayers_count"c" )
    
    for( new 
0players_counti++ )
    {
        switch( 
get_user_teamplayers] ) )
        {
            case 
1:
            {
                
count++ // terror
            
}
            case 
2:
            {
                
count++ // ct
            
}
        }
    }
    return 
floatroundcount percent )
}

/**
 * Displays a message all players and server consoles.
 *
 * @param message[] the text formatting rules to display.
 * @param any the variable number of formatting parameters.
 */
public print_at_console_to_allmessage[], any: ... )
{
    static 
formated_messageLONG_STRING ]
    
    
vformatformated_messagecharsmaxformated_message ), message)
    
    
client_print0print_consoleformated_message )
    
server_printformated_message )
}

/**
 * Print colored text to a given player_id. It has to be called to each player using its player_id
 * instead of 'LANG_PLAYER' constant. Just use the 'LANG_PLAYER' constant when using this function
 * to display to all players.
 *
 * This includes the code:
 * ConnorMcLeod's [Dyn Native] ColorChat v0.3.2 (04 jul 2013) register_dictionary_colored function:
 *   <a href="https://forums.alliedmods.net/showthread.php?p=851160">ColorChat v0.3.2</a>
 *
 * If you are at the Amx Mod X 1.8.2, you can call this function using the player_id as 0. But it
 * will use more resources to decode its arguments. To be more optimized you should call it to every
 * player on the server, to display the colored message to all players using global scope. Example:
 * @code{.cpp}
 * #if AMXX_VERSION_NUM < 183
 * new g_colored_player_id
 * new g_colored_players_number
 * new g_colored_current_index
 * new g_colored_players_ids[ 32 ]
 * #endif
 *
 * some_function()
 * {
 *     ... some code
 * #if AMXX_VERSION_NUM < 183
 *     get_players( g_colored_players_ids, g_colored_players_number, "ch" );
 *
 *     for( g_colored_current_index = 0; g_colored_current_index < g_colored_players_number;
 *          g_colored_current_index++ )
 *     {
 *         g_colored_player_id = g_colored_players_ids[ g_colored_current_index ]
 *
 *         client_print_color_internal( g_colored_player_id, "^1%L %L %L",
 *                 g_colored_player_id, "LANG_A", g_colored_player_id, "LANG_B",
 *                 g_colored_player_id, "LANG_C", any_variable_used_on_LANG_C )
 *     }
 * #else
 *     client_print_color_internal( 0, "^1%L %L %L", LANG_PLAYER, "LANG_A",
 *             LANG_PLAYER, "LANG_B", LANG_PLAYER, "LANG_C", any_variable_used_on_LANG_C );
 * #endif
 *     ... some code
 * }
 * @endcode
 *
 * If you are at the Amx Mod X 1.8.3 or superior, you can call this function using the player_id
 * as 0, to display the colored message to all players on the server.
 *
 * If you run this function on a Game Mod that do not support colored messages, they will be
 * displayed as normal messages without any errors or bad formats.
 *
 * This allow you to use '!g for green', '!y for yellow', '!t for team' color with LANGs at a
 * register_dictionary_colored file. Otherwise use '^1', '^2', '^3' and '^4'.
 *
 * @param player_id the player id.
 * @param message[] the text formatting rules to display.
 * @param any the variable number of formatting parameters.
 *
 * @see <a href="https://www.amxmodx.org/api/amxmodx/client_print_color">client_print_color</a>
 * for Amx Mod X 1.8.3 or superior.
 */
stock client_print_color_internalplayer_idmessage[], any: ... )
{
    new 
formated_messageCOLOR_MESSAGE ]
    
    if( 
g_is_color_chat_supported )
    {
#if AMXX_VERSION_NUM < 183
        
if( player_id )
        {
            
vformatformated_messagecharsmaxformated_message ), message)
            
DEBUG_LOGGER64"( in ) Player_Id: %d, Chat printed: %s"player_idformated_message )
            
            
PRINT_COLORED_MESSAGEplayer_idformated_message )
        }
        else
        {
            new 
players_array32 ]
            new 
players_number;
            
            
get_playersplayers_arrayplayers_number"ch" );
            
            
// Figure out if at least 1 player is connected
            // so we don't execute useless code
            
if( !players_number )
            {
                
DEBUG_LOGGER64"!players_number. players_number = %d"players_number )
                return;
            }
            
            new 
player_id;
            new 
string_index
            
new argument_index
            
new multi_lingual_constants_number
            
            
new params_number                     numargs();
            new Array:
multi_lingual_indexes_array ArrayCreate();
            
            
DEBUG_LOGGER64"players_number: %d, params_number: %d"players_numberparams_number )
            
            if( 
params_number >= // ML can be used
            
{
                for( 
argument_index 2argument_index params_numberargument_index++ )
                {
                    
DEBUG_LOGGER64"argument_index: %d, getarg(argument_index): %d / %s", \
                            
argument_indexgetargargument_index ), getargargument_index ) )
                    
                    
// retrieve original param value and check if it's LANG_PLAYER value
                    
if( getargargument_index ) == LANG_PLAYER )
                    {
                        
string_index 0;
                        
                        
// as LANG_PLAYER == -1, check if next param string is a registered language translation
                        
while( ( formated_messagestring_index ] =
                                     
getargargument_index 1string_index++ ) ) )
                        {
                        }
                        
formated_messagestring_index ] = 0
                        
                        DEBUG_LOGGER
64"Player_Id: %d, formated_message: %s, \
                                GetLangTransKey( formated_message ) != TransKey_Bad: %d"
, \
                                
player_idformated_message, \
                                
GetLangTransKeyformated_message ) != TransKey_Bad )
                        
                        
DEBUG_LOGGER64"(multi_lingual_constants_number: %d, string_index: %d", \
                                
multi_lingual_constants_numberstring_index )
                        
                        if( 
GetLangTransKeyformated_message ) != TransKey_Bad )
                        {
                            
// Store that argument as LANG_PLAYER so we can alter it later
                            
ArrayPushCellmulti_lingual_indexes_arrayargument_index++ );
                            
                            
// Update ML array, so we'll know 1st if ML is used,
                            // 2nd how many arguments we have to change
                            
multi_lingual_constants_number++;
                        }
                        
                        
DEBUG_LOGGER64"argument_index (after ArrayPushCell): %d"argument_index )
                    }
                }
            }
            
            
DEBUG_LOGGER64"(multi_lingual_constants_number: %d"multi_lingual_constants_number )
            
            for( --
players_numberplayers_number >= 0players_number-- )
            {
                
player_id players_arrayplayers_number ];
                
                if( 
multi_lingual_constants_number )
                {
                    for( 
argument_index 0argument_index multi_lingual_constants_numberargument_index++ )
                    {
                        
// Set all LANG_PLAYER args to player index ( = player_id )
                        // so we can format the text for that specific player
                        
setargArrayGetCellmulti_lingual_indexes_arrayargument_index ), _player_id );
                        
                        
DEBUG_LOGGER64"(argument_index: %d, player_id: %d, \
                                ArrayGetCell( multi_lingual_indexes_array, argument_index ): %d"
, \
                                
argument_indexplayer_id, \
                                
ArrayGetCellmulti_lingual_indexes_arrayargument_index ) )
                    }
                    
vformatformated_messagecharsmaxformated_message ), message)
                }
                
                
DEBUG_LOGGER64"( in ) Player_Id: %d, Chat printed: %s"player_idformated_message )
                
PRINT_COLORED_MESSAGEplayer_idformated_message )
            }
            
            
ArrayDestroymulti_lingual_indexes_array );
        }
#else
        
vformatformated_messagecharsmaxformated_message ), message)
        
DEBUG_LOGGER64"( in ) Player_Id: %d, Chat printed: %s"player_idformated_message )
        
        
client_print_colorplayer_idprint_team_defaultformated_message )
#endif
    
}
    else
    {
        
vformatformated_messagecharsmaxformated_message ), message)
        
DEBUG_LOGGER64"( in ) Player_Id: %d, Chat printed: %s"player_idformated_message )
        
        
REMOVE_COLOR_TAGSformated_message )
        
client_printplayer_idprint_chatformated_message )
    }
    
    
// this is to show the immediate results, as the plugin is usually controlled by the server
    // or the player console.
    
if( player_id )
    {
        
client_printplayer_idprint_consoleformated_message )
    }
    else
    {
        
server_printformated_message )
    }
    
    
DEBUG_LOGGER64"( out ) Player_Id: %d, Chat printed: %s"player_idformated_message )
}

/**
 * ConnorMcLeod's [Dyn Native] ColorChat v0.3.2 (04 jul 2013) register_dictionary_colored function:
 *   <a href="https://forums.alliedmods.net/showthread.php?p=851160">ColorChat v0.3.2</a>
 *
 * @param filename the dictionary file name including its file extension.
 */
stock register_dictionary_colored( const filename[] )
{
    if( !
register_dictionaryfilename ) )
    {
        return 
0;
    }
    
    new 
szFileName256 ];
    
get_localinfo"amxx_datadir"szFileNamecharsmaxszFileName ) );
    
formatexszFileNamecharsmaxszFileName ), "%s/lang/%s"szFileNamefilename );
    new 
fp fopenszFileName"rt" );
    
    if( !
fp )
    {
        
log_amx"Failed to open %s"szFileName );
        return 
0;
    }
    
    new 
szBuffer512 ], szLang], szKey64 ], szTranslation256 ], TransKey:iKey;
    
    while( !
feoffp ) )
    {
        
fgetsfpszBuffercharsmaxszBuffer ) );
        
trimszBuffer );
        
        if( 
szBuffer] == '[' )
        {
            
strtokszBuffer], szLangcharsmaxszLang ), szBuffer1']' );
        }
        else if( 
szBuffer] )
        {
        
#if AMXX_VERSION_NUM < 183
            
strbreakszBufferszKeycharsmaxszKey ), szTranslationcharsmaxszTranslation ) );
        
#else
            
argbreakszBufferszKeycharsmaxszKey ), szTranslationcharsmaxszTranslation ) );
        
#endif
            
iKey GetLangTransKeyszKey );
            
            if( 
iKey != TransKey_Bad )
            {
                
INSERT_COLOR_TAGSszTranslation )
                
AddTranslationszLangiKeyszTranslation] );
            }
        }
    }
    
    
fclosefp );
    return 
1;



gabuch2 06-01-2019 21:11

Re: Multi-Mod Manager v1.1-release_candidate1.hotfix1 | Last Update: 21.01.2016
 
Is this mod still updated?

Tried installing it in my server but it doesn't seem to work.

Code:

L 06/02/2019 - 01:10:20: -------- Mapchange to stalkyard --------
[AMXX] Loaded 9 admins from file
[AMXX] Plugin Loading Music II initialized for HLDM mod

Currently loaded plugins:
      name                    version    author            file            status
 [  1] Multi-Mod Manager      1.1-rc1.1  Addons zz        multimod_manage  running

 [ 18] Galileo                v5.9.1-926  Brad Jones/Addon  galileo.amxx    running

I followed the instructions provided in the OP, I have 4 different mods, it doesn't seem to load the .amxx files.

EDIT: Apparently it's working, but I need to vote on a mod first using amx_votemod.

Another issue I found is that the Multi-Mod is applying the configuration files after the mod has loaded. if a plugin depends on a specific setup to load correctly it will fail to load.

Any way to load the next mod's config file in the intermission? It would fix this problem.

fysiks 06-02-2019 00:56

Re: Multi-Mod Manager v1.1-release_candidate1.hotfix1 | Last Update: 21.01.2016
 
So, was Polymorph not working for you?

Rivotril 06-02-2019 10:02

Re: Multi-Mod Manager v1.1-release_candidate1.hotfix1 | Last Update: 21.01.2016
 
Quote:

Originally Posted by Gabe Iggy (Post 2654027)
Is this mod still updated?

Tried installing it in my server but it doesn't seem to work.

Code:

L 06/02/2019 - 01:10:20: -------- Mapchange to stalkyard --------
[AMXX] Loaded 9 admins from file
[AMXX] Plugin Loading Music II initialized for HLDM mod

Currently loaded plugins:
      name                    version    author            file            status
 [  1] Multi-Mod Manager      1.1-rc1.1  Addons zz        multimod_manage  running

 [ 18] Galileo                v5.9.1-926  Brad Jones/Addon  galileo.amxx    running

I followed the instructions provided in the OP, I have 4 different mods, it doesn't seem to load the .amxx files.

EDIT: Apparently it's working, but I need to vote on a mod first using amx_votemod.

Another issue I found is that the Multi-Mod is applying the configuration files after the mod has loaded. if a plugin depends on a specific setup to load correctly it will fail to load.

Any way to load the next mod's config file in the intermission? It would fix this problem.

I wouldn't recommend you this, it has quite some issues, try polymorph instead.

Siska1 06-19-2022 12:36

Re: Multi-Mod Manager v1.1-release_candidate1.hotfix1 | Last Update: 21.01.2016
 
when I write amx_votemod I choose a mode, but I immediately have a vote for a map, and in the vote are the maps from the current mode. Why does this happen ? How can I vote for a mod and switch immediately to the next mod with the corresponding maps ?

Siska1 06-29-2022 07:10

Re: Multi-Mod Manager v1.1-release_candidate1.hotfix1 | Last Update: 21.01.2016
 
How to stop csdm for other mods ?
does not want to stop at other mods...

fysiks 06-29-2022 22:34

Re: Multi-Mod Manager v1.1-release_candidate1.hotfix1 | Last Update: 21.01.2016
 
Quote:

Originally Posted by Siska1 (Post 2782700)
How to stop csdm for other mods ?
does not want to stop at other mods...

I created a plugin to do this for Polymorph, should work similarly here: https://forums.alliedmods.net/showpo...39&postcount=2

Siska1 06-30-2022 16:07

Re: Multi-Mod Manager v1.1-release_candidate1.hotfix1 | Last Update: 21.01.2016
 
Quote:

Originally Posted by fysiks (Post 2782726)
I created a plugin to do this for Polymorph, should work similarly here: https://forums.alliedmods.net/showpo...39&postcount=2

However, neither poly_off nor disabled works here.
I have no idea why, but whatever I do csdm continues to work constantly.
Not so with your plugin, but there is no option to change mods and maps.

fysiks 06-30-2022 21:25

Re: Multi-Mod Manager v1.1-release_candidate1.hotfix1 | Last Update: 21.01.2016
 
Quote:

Originally Posted by Siska1 (Post 2782770)
However, neither poly_off nor disabled works here.
I have no idea why, but whatever I do csdm continues to work constantly.
Not so with your plugin, but there is no option to change mods and maps.

The plugin that I'm pointing to is "poly_csdm_off.amxx". It simply calls the CSDM function to disable it. I would say that you should test to see if it works without all this other stuff.
  • Simply run a normal map with the normal map chooser (or no map chooser).
  • Make sure that CSDM is running and functioning like normal.
  • Edit plugins.ini to add "poly_csdm_off.amxx".
  • Change the map to the same map using amx_map.
  • Check if CSDM is still functioning or not.

If CSDM is still functioning, check your error logs. Check the output of "amxx list" (as commanded from the server's console e.g. via HLSW or equivalent) to see if the "poly_csdm_off.amxx" is properly loaded (post the "amxx list" output here).

Siska1 07-02-2022 05:37

Re: Multi-Mod Manager v1.1-release_candidate1.hotfix1 | Last Update: 21.01.2016
 
Quote:

Originally Posted by fysiks (Post 2782786)
The plugin that I'm pointing to is "poly_csdm_off.amxx". It simply calls the CSDM function to disable it. I would say that you should test to see if it works without all this other stuff.
  • Simply run a normal map with the normal map chooser (or no map chooser).
  • Make sure that CSDM is running and functioning like normal.
  • Edit plugins.ini to add "poly_csdm_off.amxx".
  • Change the map to the same map using amx_map.
  • Check if CSDM is still functioning or not.

If CSDM is still functioning, check your error logs. Check the output of "amxx list" (as commanded from the server's console e.g. via HLSW or equivalent) to see if the "poly_csdm_off.amxx" is properly loaded (post the "amxx list" output here).

I already wrote this in your topic...

addons_zz 07-02-2022 09:42

Re: Multi-Mod Manager v1.1-release_candidate1.hotfix1 | Last Update: 21.01.2016
 
Quote:

Originally Posted by Siska1 (Post 2782700)
How to stop csdm for other mods ?
does not want to stop at other mods...

Hi there are about 6 years I do not use this, but you can try this.

If you edit every other mod file except for `addons\amxmodx\configs\multimod\cfg\csdm.cfg ` i.e.,
  1. addons\amxmodx\configs\multimod\cfg\catch.cfg
  2. addons\amxmodx\configs\multimod\cfg\deathrun. cfg
  3. addons\amxmodx\configs\multimod\cfg\gungame.c fg
  4. addons\amxmodx\configs\multimod\cfg\surf.cfg
  5. etc
And add something like `amxx pause csdm_main` and others, it should disable csdm. If you use the meta mod version of csdm you can use something like `meta unload csdm`. From where did you download your csdm so I can take a look?

You can find my multimode configuration at Multi-Mod Plugin v2.0 and use it as an example to configure your own.

Siska1 07-03-2022 01:58

Re: Multi-Mod Manager v1.1-release_candidate1.hotfix1 | Last Update: 21.01.2016
 
In the end, does anyone have any idea why when I type votemod every time it says that the mod is already selected?


All times are GMT -4. The time now is 11:23.

Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.