├── .editorconfig
├── .gitattributes
├── .github
├── CODE_OF_CONDUCT.md
├── FUNDING.yml
├── LICENSE
├── README.md
└── workflows
│ └── CI.yml
├── .gitignore
└── cstrike
└── addons
└── amxmodx
├── configs
├── plugins-ChatAdditions.ini
└── plugins
│ └── ChatAdditions
│ ├── CA_Addon_DeathMute.cfg
│ ├── CA_Addon_RankRestrictions.cfg
│ ├── CA_Addon_RequestUnGag.cfg
│ ├── CA_AntiFlood.cfg
│ ├── CA_Gag.cfg
│ ├── CA_Mute.cfg
│ ├── CA_Storage_CSBans.cfg
│ ├── CA_Storage_GameCMS.cfg
│ ├── CA_Storage_PGBans.cfg
│ ├── ChatAdditions_core.cfg
│ ├── ca_gag_chat_whitelist_cmds.cfg
│ └── ca_gag_reasons.cfg
├── data
└── lang
│ ├── CA_Addon_DeathMute.txt
│ ├── CA_Addon_RankRestrictions.txt
│ ├── CA_Addon_RequestUngag.txt
│ ├── CA_AntiFlood.txt
│ ├── CA_Gag.txt
│ └── CA_Mute.txt
└── scripting
├── ChatAdditions
├── Addons
│ ├── CA_Addon_DeathMute.sma
│ ├── CA_Addon_RankRestrictions.sma
│ ├── CA_Addon_RequestUnGag.sma
│ └── CA_Addon_VoteGag.sma
├── CA_AntiFlood.sma
├── CA_Gag.sma
├── CA_Mute.sma
├── ChatAdditions_Core.sma
└── Storage
│ ├── CA_Storage_CSBans.sma
│ ├── CA_Storage_GameCMS.sma
│ ├── CA_Storage_PGBans.sma
│ └── CA_Storage_SQLite.sma
└── include
├── CA_GAG_API.inc
├── CA_StorageAPI.inc
├── CA_StorageAPI_endpoint.inc
├── ChatAdditions.inc
├── cellqueue.inc
└── easy_http.inc
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig is awesome: https://EditorConfig.org
2 |
3 | # top-most EditorConfig file
4 | root = true
5 |
6 | # Unix-style newlines with a newline ending every file
7 | [*]
8 | end_of_line = lf
9 | insert_final_newline = true
10 | charset = utf-8
11 |
12 | # Set default charset
13 | [*.{sma,inc,sh}]
14 | indent_style = space
15 | indent_size = 4
16 | trim_trailing_whitespace = true
17 |
18 | [{.vscode/*,.github/*}]
19 | indent_style = space
20 | indent_size = 4
21 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto
2 |
--------------------------------------------------------------------------------
/.github/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | We as members, contributors, and leaders pledge to make participation in our
6 | community a harassment-free experience for everyone, regardless of age, body
7 | size, visible or invisible disability, ethnicity, sex characteristics, gender
8 | identity and expression, level of experience, education, socio-economic status,
9 | nationality, personal appearance, race, religion, or sexual identity
10 | and orientation.
11 |
12 | We pledge to act and interact in ways that contribute to an open, welcoming,
13 | diverse, inclusive, and healthy community.
14 |
15 | ## Our Standards
16 |
17 | Examples of behavior that contributes to a positive environment for our
18 | community include:
19 |
20 | * Demonstrating empathy and kindness toward other people
21 | * Being respectful of differing opinions, viewpoints, and experiences
22 | * Giving and gracefully accepting constructive feedback
23 | * Accepting responsibility and apologizing to those affected by our mistakes,
24 | and learning from the experience
25 | * Focusing on what is best not just for us as individuals, but for the
26 | overall community
27 |
28 | Examples of unacceptable behavior include:
29 |
30 | * The use of sexualized language or imagery, and sexual attention or
31 | advances of any kind
32 | * Trolling, insulting or derogatory comments, and personal or political attacks
33 | * Public or private harassment
34 | * Publishing others' private information, such as a physical or email
35 | address, without their explicit permission
36 | * Other conduct which could reasonably be considered inappropriate in a
37 | professional setting
38 |
39 | ## Enforcement Responsibilities
40 |
41 | Community leaders are responsible for clarifying and enforcing our standards of
42 | acceptable behavior and will take appropriate and fair corrective action in
43 | response to any behavior that they deem inappropriate, threatening, offensive,
44 | or harmful.
45 |
46 | Community leaders have the right and responsibility to remove, edit, or reject
47 | comments, commits, code, wiki edits, issues, and other contributions that are
48 | not aligned to this Code of Conduct, and will communicate reasons for moderation
49 | decisions when appropriate.
50 |
51 | ## Scope
52 |
53 | This Code of Conduct applies within all community spaces, and also applies when
54 | an individual is officially representing the community in public spaces.
55 | Examples of representing our community include using an official e-mail address,
56 | posting via an official social media account, or acting as an appointed
57 | representative at an online or offline event.
58 |
59 | ## Enforcement
60 |
61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
62 | reported to the community leaders responsible for enforcement at
63 | wopox1337@ya.ru
64 | All complaints will be reviewed and investigated promptly and fairly.
65 |
66 | All community leaders are obligated to respect the privacy and security of the
67 | reporter of any incident.
68 |
69 | ## Enforcement Guidelines
70 |
71 | Community leaders will follow these Community Impact Guidelines in determining
72 | the consequences for any action they deem in violation of this Code of Conduct:
73 |
74 | ### 1. Correction
75 |
76 | **Community Impact**: Use of inappropriate language or other behavior deemed
77 | unprofessional or unwelcome in the community.
78 |
79 | **Consequence**: A private, written warning from community leaders, providing
80 | clarity around the nature of the violation and an explanation of why the
81 | behavior was inappropriate. A public apology may be requested.
82 |
83 | ### 2. Warning
84 |
85 | **Community Impact**: A violation through a single incident or series
86 | of actions.
87 |
88 | **Consequence**: A warning with consequences for continued behavior. No
89 | interaction with the people involved, including unsolicited interaction with
90 | those enforcing the Code of Conduct, for a specified period of time. This
91 | includes avoiding interactions in community spaces as well as external channels
92 | like social media. Violating these terms may lead to a temporary or
93 | permanent ban.
94 |
95 | ### 3. Temporary Ban
96 |
97 | **Community Impact**: A serious violation of community standards, including
98 | sustained inappropriate behavior.
99 |
100 | **Consequence**: A temporary ban from any sort of interaction or public
101 | communication with the community for a specified period of time. No public or
102 | private interaction with the people involved, including unsolicited interaction
103 | with those enforcing the Code of Conduct, is allowed during this period.
104 | Violating these terms may lead to a permanent ban.
105 |
106 | ### 4. Permanent Ban
107 |
108 | **Community Impact**: Demonstrating a pattern of violation of community
109 | standards, including sustained inappropriate behavior, harassment of an
110 | individual, or aggression toward or disparagement of classes of individuals.
111 |
112 | **Consequence**: A permanent ban from any sort of public interaction within
113 | the community.
114 |
115 | ## Attribution
116 |
117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage],
118 | version 2.0, available at
119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
120 |
121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct
122 | enforcement ladder](https://github.com/mozilla/diversity).
123 |
124 | [homepage]: https://www.contributor-covenant.org
125 |
126 | For answers to common questions about this code of conduct, see the FAQ at
127 | https://www.contributor-covenant.org/faq. Translations are available at
128 | https://www.contributor-covenant.org/translations.
129 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4 | patreon: # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
13 | custom: [ 'https://www.paypal.me/wopox1337', 'https://yoomoney.ru/to/410011388660403']
14 |
15 |
--------------------------------------------------------------------------------
/.github/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Chat Additions
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/.github/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | AMXModX plugin chat control tool with rich functionality and API.
6 |
7 |
8 |
9 |
11 |
12 |
14 |
15 |
17 |
18 |
20 |
21 |
23 |
24 |
25 |
26 | About •
27 | Requirements •
28 | Installation •
29 | Updating •
30 | Downloads •
31 | Features •
32 | Wiki •
33 | Contributing •
34 | Credits
35 |
36 |
37 | ---
38 |
39 | ## About
40 | Chat Additions is a set of tools for managing voice as well as text chat, for your HLDS server.
41 | Allows you to fully or selectively limit the player to use any chat (voice, general, team, admin).
42 | Modular system, allows you to use only the necessary tasks capabilities, thereby saving server resources.
43 | Rich API capabilities allow the system to connect any functionality (work with player statistics, automation of decisions on blocking).
44 |
45 |
46 |
47 |
48 | ## Requirements
49 | - HLDS installed;
50 | - [ReGameDLL](https://github.com/s1lentq/ReGameDLL_CS) installed;
51 | - Installed AMXModX ([`v1.9`](https://www.amxmodx.org/downloads-new.php) or [`v1.10`](https://www.amxmodx.org/downloads-new.php?branch=master));
52 | - Installed [ReAPI](https://github.com/s1lentq/reapi) module (optional, but not required);
53 | - Installed [AmxxEasyHttp](https://github.com/Next21Team/AmxxEasyHttp) module (optional, but not required);
54 |
55 | ## Installation
56 | - [Download the latest](https://github.com/ChatAdditions/ChatAdditions_AMXX/releases/latest) stable version from the release section.
57 | - Extract the `cstrike` folder to the root folder of the HLDS server;
58 | - Make sure that all plugins are running and in the correct order, using the `amxx list` command.
59 |
60 | ## Updating
61 | - Put new plugins and lang-files (`plugins/*.amxx` & `data/lang/*.txt`) into `amxmodx/` folder on the HLDS server;
62 | - Restart the server (command `restart` or change the map);
63 | - Make sure that the versions of the plugins are up to date with the command `amxx list`.
64 |
65 | ## Downloads
66 | - [Release builds](https://github.com/ChatAdditions/ChatAdditions_AMXX/releases)
67 | - [Dev builds](https://github.com/ChatAdditions/ChatAdditions_AMXX/actions/workflows/CI.yml)
68 |
69 | ## Features
70 | - Compatibility with any chat manager;
71 | - No [`VoiceTranscoder`](https://github.com/WPMGPRoSToTeMa/VoiceTranscoder) or [`ReVoice`](https://github.com/s1lentq/revoice/) required;
72 | - Flexible system of access rights and immunities for players;
73 | - Modular system, rich API capabilities, and flexibility;
74 | - Simple, intuitive interface (UX);
75 | - Multi-language support;
76 | - Simple, user-friendly configuration;
77 | - `CA_Gag`: Simple, flexible templates system (reasons, times, punishment type);
78 | - `CA_Gag`: Support for SQLite, MySQL, CSBans, GameCMS;
79 | - User-friendly logging system with good customization;
80 | - Up-to-date support and updates.
81 |
82 | ## Wiki
83 | Do you **need some help**? Check the _articles_ from the [wiki](https://github.com/ChatAdditions/ChatAdditions_AMXX/wiki).
84 |
85 | ## Contributing
86 | Got **something interesting** you'd like to **share**? Learn about [contributing](CONTRIBUTING.md).
87 |
88 | ## Credits
89 | I would like to thank the creators of AMXModX and ReAPI and everyone who helps me in developing and testing this system, who supports my interest.
90 |
91 | **Thank you guys! 👍**
92 |
93 | ## Support
94 | Reach out to me at one of the following places:
95 | - Github issues;
96 | - Github discussions;
97 | - [Telegram](https://t.me/ShorokhovSergey);
98 | - [Telegram group](https://t.me/ChatAdditions_group);
99 | - E-Mail;
100 |
101 | ## License
102 | [](LICENSE)
103 | Copyright © Sergey Shorokhov
104 |
--------------------------------------------------------------------------------
/.github/workflows/CI.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on:
4 | push:
5 | branches: [master]
6 | paths-ignore:
7 | - "**.md"
8 |
9 | pull_request:
10 | types: [opened, reopened, synchronize]
11 | release:
12 | types: [published]
13 |
14 | jobs:
15 | build:
16 | name: "Build"
17 | runs-on: ubuntu-latest
18 | outputs:
19 | sha: ${{ steps.declare_sha.outputs.sha }}
20 | semver: ${{ steps.declare_sha.outputs.semver }}
21 | steps:
22 | - name: Checkout
23 | uses: actions/checkout@v4.1.1
24 | with:
25 | fetch-depth: 0
26 |
27 | - name: Parse SemVer string (release)
28 | id: semver_parser
29 | if: |
30 | github.event_name == 'release' &&
31 | github.event.action == 'published' &&
32 | startsWith(github.ref, 'refs/tags/')
33 | uses: booxmedialtd/ws-action-parse-semver@v1.4.7
34 | with:
35 | input_string: ${{ github.ref }}
36 | version_extractor_regex: '\/v(.*)$'
37 |
38 | - name: Declare SHA & package name
39 | id: declare_sha
40 | shell: bash
41 | run: |
42 | SHA=$(git rev-parse --short HEAD)
43 | echo "COMMIT_SHA=${SHA}" >> $GITHUB_ENV
44 |
45 | echo "sha=$SHA" >> $GITHUB_OUTPUT
46 | echo "semver=${{ steps.semver_parser.outputs.fullversion }}" >> $GITHUB_OUTPUT
47 |
48 | - name: Setup latest ReAPI includes
49 | env:
50 | REPO: "s1lentq/reapi"
51 | run: |
52 | mkdir -p dep/reapi
53 | cd dep/reapi
54 |
55 | curl \
56 | --silent \
57 | https://api.github.com/repos/$REPO/releases/latest | \
58 | grep "browser_download_url" | \
59 | grep -Eo 'https://[^\"]*' | \
60 | xargs wget
61 |
62 | 7z x *.zip
63 |
64 | echo "REAPI_INCLUDE_PATH=$(pwd)/addons/amxmodx/scripting/include" >> $GITHUB_ENV
65 |
66 | - name: Update versions for plugins (release)
67 | working-directory: cstrike/addons/amxmodx/scripting/include/
68 | if: |
69 | github.event_name == 'release' &&
70 | github.event.action == 'published' &&
71 | startsWith(github.ref, 'refs/tags/')
72 | env:
73 | PLUGIN_VERSION: "v${{ steps.semver_parser.outputs.fullversion }}"
74 | run: sed -i "s|%CA_VERSION%|$PLUGIN_VERSION|g" ChatAdditions.inc
75 |
76 | - name: Update versions for plugins (only for artifacts builds)
77 | working-directory: cstrike/addons/amxmodx/scripting/include/
78 | env:
79 | PLUGIN_VERSION: "${{ env.COMMIT_SHA }}"
80 | run: sed -i "s|%CA_VERSION%|$PLUGIN_VERSION|g" ChatAdditions.inc
81 |
82 | - name: Setup AMXXPawn Compiler
83 | uses: wopox1337/setup-amxxpawn@v1.1.0
84 | with:
85 | version: "1.10.5466"
86 |
87 | - name: Compile AMXX plugins
88 | working-directory: cstrike/addons/amxmodx/scripting/
89 | env:
90 | REAPI_INCLUDE: ${{env.REAPI_INCLUDE_PATH}}
91 | run: |
92 | mkdir ../plugins/
93 |
94 | compile() {
95 | sourcefile=$1
96 | amxxfile="$(echo $sourcefile | sed -e 's/\.sma$/.amxx/')"
97 | output_path="../plugins/$amxxfile"
98 |
99 | mkdir -p $(dirname $output_path)
100 |
101 | echo -n "Compiling $sourcefile ... "
102 | amxxpc $sourcefile -o"$output_path" \
103 | -i"include" \
104 | -i"$REAPI_INCLUDE"
105 | }
106 | export -f compile
107 |
108 | find * -type f -name "*.sma" -exec bash -c 'compile "$0"' {} \;
109 |
110 | - name: Move files
111 | run: |
112 | mkdir publish
113 | mv cstrike/ publish/
114 |
115 | - name: Upload artifact
116 | uses: actions/upload-artifact@v4.3.1
117 | with:
118 | name: ChatAdditions-${{ env.COMMIT_SHA }}-dev
119 | path: publish/*
120 |
121 | publish:
122 | name: "Publish"
123 | runs-on: ubuntu-latest
124 | needs: [build]
125 | if: |
126 | github.event_name == 'release' &&
127 | github.event.action == 'published' &&
128 | startsWith(github.ref, 'refs/tags/')
129 | steps:
130 | - name: Download artifacts
131 | uses: actions/download-artifact@v4.1.4
132 | with:
133 | name: ChatAdditions-${{needs.build.outputs.sha}}-dev
134 |
135 | - name: Packaging binaries
136 | id: packaging
137 | run: 7z a -mm=Deflate -mfb=258 -mpass=15 -r ChatAdditions-v${{needs.build.outputs.semver}}.zip cstrike/
138 |
139 | - name: Publish artifacts
140 | uses: softprops/action-gh-release@v2.0.4
141 | id: publish-job
142 | if: |
143 | startsWith(github.ref, 'refs/tags/') &&
144 | steps.packaging.outcome == 'success'
145 | env:
146 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
147 | with:
148 | files: |
149 | *.zip
150 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.amxx
2 | .vscode/*
3 | *publish/
4 | /.temp
5 | /.compiler
--------------------------------------------------------------------------------
/cstrike/addons/amxmodx/configs/plugins-ChatAdditions.ini:
--------------------------------------------------------------------------------
1 | ; A core plugin for control different types of chat.
2 | ChatAdditions/ChatAdditions_Core.amxx debug
3 |
4 | ; Storage choose (disable not used storages)
5 | ; IMPORTANT: you must leave ONLY ONE plugin to manage the storage.
6 | ChatAdditions/Storage/CA_Storage_SQLite.amxx debug ; SQLite storage provider
7 | ; ChatAdditions/Storage/CA_Storage_CSBans.amxx debug ; CSBans (MySQL) storage provider
8 | ; ChatAdditions/Storage/CA_Storage_GameCMS.amxx debug ; GameCMS (MySQL) storage provider
9 |
10 | ; Extensions
11 | ChatAdditions/CA_AntiFlood.amxx debug ; Antiflood for chat
12 | ChatAdditions/CA_Mute.amxx debug ; Players can choose who they can hear.
13 | ChatAdditions/Addons/CA_Addon_DeathMute.amxx debug ; Alive players don't hear dead players after 5 secs
14 | ChatAdditions/Addons/CA_Addon_RankRestrictions.amxx debug ; Restrict chat until you reach the rank of a statistic.
15 | ChatAdditions/Addons/CA_Addon_VoteGag.amxx debug ; Ability for players to vote for gag.
16 | ChatAdditions/Addons/CA_Addon_RequestUnGag.amxx debug ; A player can apologize to the administration.
17 | ChatAdditions/CA_Gag.amxx debug ; Manage player chats for the admin.
18 |
19 | ; IMPORTANT: Place you chat manager below (Chat RBS plugins, Lite Translit, Colored Translit etc..)
20 | ; Most chat managers are not written using the correct chat handling,
21 | ; for this reason player messages may not be blocked.
22 | ; It is necessary to place the chat manager below the chat blocking plugins,
23 | ; to avoid blocking problems.
24 | ; chat_rbs.amxx
25 | ; crx_chatmanager.amxx
26 | ; lite_translit.amxx
27 | ; colored_translit.amxx
28 |
--------------------------------------------------------------------------------
/cstrike/addons/amxmodx/configs/plugins/ChatAdditions/CA_Addon_DeathMute.cfg:
--------------------------------------------------------------------------------
1 | // Time (in seconds) for killed players, during which they can report information to living players.
2 | // 0 - disabled functionality
3 | // -
4 | // Default: "5.0"
5 | // Minimum: "0.000000"
6 | // Maximum: "240.000000"
7 | ca_deathmute_time "5.0"
8 |
9 | // Death mute mode
10 | // 0 - alive hear only alive, dead hear all
11 | // 1 - alive hear only alive, dead hear only dead
12 | // -
13 | // Default: "1"
14 | // Minimum: "0.000000"
15 | // Maximum: "1.000000"
16 | ca_deathmute_dead_hear_alive "1"
17 |
18 | // Notification type for dead players
19 | // 0 - disabled functionality
20 | // 1 - chat message
21 | // 2 - HUD message
22 | // -
23 | // Default: "1"
24 | ca_deathmute_notify_type "1"
25 |
26 | // Show progressbar
27 | // 0 - disabled functionality
28 | // -
29 | // Default: "1"
30 | ca_deathmute_notify_show_progressbar "1"
31 |
32 | // X position for HUD message
33 | // -1.0 - center
34 | // -
35 | // Default: "-1.0"
36 | // Minimum: "-1.000000"
37 | // Maximum: "1.000000"
38 | ca_deathmute_notify_hud_x "-1.0"
39 |
40 | // Y position for HUD message
41 | // -1.0 - center
42 | // -
43 | // Default: "0.15"
44 | // Minimum: "-1.000000"
45 | // Maximum: "1.000000"
46 | ca_deathmute_notify_hud_y "0.15"
47 |
48 | // Red color value (in RGB) [0...255]
49 | // -
50 | // Default: "200"
51 | // Minimum: "0.000000"
52 | // Maximum: "255.000000"
53 | ca_deathmute_notify_hud_r "200"
54 |
55 | // Green color value (in RGB) [0...255]
56 | // -
57 | // Default: "50"
58 | // Minimum: "0.000000"
59 | // Maximum: "255.000000"
60 | ca_deathmute_notify_hud_g "50"
61 |
62 | // Blue color value (in RGB) [0...255]
63 | // -
64 | // Default: "0"
65 | // Minimum: "0.000000"
66 | // Maximum: "255.000000"
67 | ca_deathmute_notify_hud_b "0"
68 |
69 | // User immunity flag
70 | // -
71 | // Default: "a"
72 | ca_deathmute_immunity_flags "a"
73 |
--------------------------------------------------------------------------------
/cstrike/addons/amxmodx/configs/plugins/ChatAdditions/CA_Addon_RankRestrictions.cfg:
--------------------------------------------------------------------------------
1 | // Restrictions Type
2 | // 0 - Disable restrictions
3 | // 1 - Level restrictions
4 | // 2 - Kills count restrictions
5 | // -
6 | // Default: "1"
7 | // Minimum: "0.000000"
8 | // Maximum: "2.000000"
9 | ca_rankrestrictions_type "1"
10 |
11 | // Kill System Types
12 | // 0 - CSStats MySQL
13 | // 1 - CSX Module
14 | // -
15 | // Default: "1"
16 | // Minimum: "0.000000"
17 | // Maximum: "1.000000"
18 | ca_rankrestrictions_type_kills "1"
19 |
20 | // Min kills count to access VOICE chat
21 | // -
22 | // Default: "10"
23 | // Minimum: "0.000000"
24 | ca_rankrestrictions_min_kills_voice_chat "10"
25 |
26 | // Min kills count to access TEXT chat
27 | // -
28 | // Default: "10"
29 | // Minimum: "0.000000"
30 | ca_rankrestrictions_min_kills_text_chat "10"
31 |
32 | // Level System Types
33 | // 0 - Advanced Experience System
34 | // 1 - Army Ranks Ultimate
35 | // 2 - OciXCrom's Rank System
36 | // 3 - CMSStats Ranks
37 | // 4 - CMSStats MySQL
38 | // 5 - CSstatsX SQL
39 | // 6 - CSX Module
40 | // -
41 | // Default: "1"
42 | // Minimum: "0.000000"
43 | // Maximum: "6.000000"
44 | ca_rankrestrictions_type_level "1"
45 |
46 | // Min Level to access VOICE chat
47 | // -
48 | // Default: "2"
49 | // Minimum: "0.000000"
50 | ca_rankrestrictions_min_level_voice_chat "2"
51 |
52 | // Min Level to access TEXT chat
53 | // -
54 | // Default: "2"
55 | // Minimum: "0.000000"
56 | ca_rankrestrictions_min_level_text_chat "2"
57 |
58 | // User immunity flag
59 | // -
60 | // Default: "a"
61 | ca_rankrestrictions_immunity_flag "a"
62 |
63 | // Enable immunity for steam players
64 | // -
65 | // Default: "0"
66 | // Minimum: "0.000000"
67 | // Maximum: "1.000000"
68 | ca_rankrestrictions_steam_immunity "0"
69 |
--------------------------------------------------------------------------------
/cstrike/addons/amxmodx/configs/plugins/ChatAdditions/CA_Addon_RequestUnGag.cfg:
--------------------------------------------------------------------------------
1 | // Request ungag command
2 | // -
3 | // Default: "/sorry"
4 | ca_requestungag_cmd "/sorry"
5 |
6 | // delay time request ungag
7 | // -
8 | // Default: "40.0"
9 | // Minimum: "1.000000"
10 | ca_requestungag_delay "40.0"
11 |
--------------------------------------------------------------------------------
/cstrike/addons/amxmodx/configs/plugins/ChatAdditions/CA_AntiFlood.cfg:
--------------------------------------------------------------------------------
1 | // Time between messages
2 | // 0.0 - no limit
3 | // -
4 | // Default: "0.75"
5 | // Minimum: "0.000000"
6 | ca_anti_flood_time "0.75"
7 |
8 | // How many identical messages can be written in a row
9 | // 0 - no limit
10 | // -
11 | // Default: "2"
12 | // Minimum: "0.000000"
13 | ca_equal_messages "2"
14 |
--------------------------------------------------------------------------------
/cstrike/addons/amxmodx/configs/plugins/ChatAdditions/CA_Gag.cfg:
--------------------------------------------------------------------------------
1 | // Gag time values for choose
2 | // format: 1 = 1 second, 1i = 1 minute, 1h = 1 hour, 1d = 1 day, 1w = 1 week, 1m = 1 month, 1y = 1 year
3 | // NOTE: Changes will be applied only after reloading the map (or command `ca_gag_reload_config`)
4 | // -
5 | // Default: "1i, 5i, 10i, 30i, 1h, 1d, 1w, 1m"
6 | ca_gag_times "1i, 5i, 10i, 30i, 1h, 1d, 1w, 1m"
7 |
8 | // User immunity flag
9 | // users with this flag can't be gagged
10 | // NOTE: `ca_gag_access_flags_high` can gag this users
11 | // -
12 | // Default: "a"
13 | ca_gag_immunity_flags "a"
14 |
15 | // Admin flag
16 | // users with this flag can gag users with flag `z`, but can't with flag `ca_gag_immunity_flags`
17 | // users with this flag can't be gagged by same flags users (immunity)
18 | // NOTE: `ca_gag_access_flags_high` can gag this users
19 | // -
20 | // Default: "c"
21 | ca_gag_access_flags "c"
22 |
23 | // Admin flag
24 | // users with this flag can enter their own gag reason
25 | // -
26 | // Default: "d"
27 | ca_gag_access_flags_own_reason "d"
28 |
29 | // Admin flag
30 | // users with this flag can enter their own gag time
31 | // -
32 | // Default: "e"
33 | ca_gag_access_flags_own_time "e"
34 |
35 | // High admin flag
36 | // users with this flag can everyone
37 | // users with this flag can't be gagged
38 | // NOTE: `ca_gag_access_flags_high` can gag this users
39 | // -
40 | // Default: "l"
41 | ca_gag_access_flags_high "l"
42 |
43 | // Remove gag access control
44 | // 1 = remove only own gags
45 | // 0 = no restrictions
46 | // NOTE: `ca_gag_access_flags_high` can remove every gag
47 | // -
48 | // Default: "1"
49 | ca_gag_remove_only_own_gag "1"
50 |
51 | // Sound for success action
52 | // NOTE: Changes will be applied only after reloading the map
53 | // -
54 | // Default: "buttons/blip2.wav"
55 | ca_gag_sound_ok "buttons/blip2.wav"
56 |
57 | // Sound for error action
58 | // NOTE: Changes will be applied only after reloading the map
59 | // -
60 | // Default: "buttons/button2.wav"
61 | ca_gag_sound_error "buttons/button2.wav"
62 |
63 | // Block nickname change for gagged player
64 | // 0 = no restrictions
65 | // -
66 | // Default: "1"
67 | ca_gag_block_nickname_change "1"
68 |
69 | // Also block adminchat if admin gagged
70 | // 0 = no restrictions
71 | // -
72 | // Default: "1"
73 | ca_gag_block_admin_chat "1"
74 |
75 | // Don't separate `say` & `say_team` chats
76 | // 0 = disabled
77 | // -
78 | // Default: "1"
79 | ca_gag_common_chat_block "1"
80 |
81 | // Enable own gag reason
82 | // 0 = disabled (excluding when there are no reasons)
83 | // 1 = enabled, at first position in reasons list
84 | // 2 = enabled, at last position in reasons list
85 | // -
86 | // Default: "1"
87 | ca_gag_own_reason_enabled "1"
88 |
--------------------------------------------------------------------------------
/cstrike/addons/amxmodx/configs/plugins/ChatAdditions/CA_Mute.cfg:
--------------------------------------------------------------------------------
1 | // How often players can use menu. (in seconds)
2 | // -
3 | // Default: "3"
4 | // Minimum: "0.000000"
5 | // Maximum: "120.000000"
6 | ca_mute_use_delay "3"
7 |
8 | // Save the player's individual preferences in the vault.
9 | // -
10 | // Default: "1"
11 | // Minimum: "0.000000"
12 | // Maximum: "1.000000"
13 | ca_mute_use_storage "1"
14 |
--------------------------------------------------------------------------------
/cstrike/addons/amxmodx/configs/plugins/ChatAdditions/CA_Storage_CSBans.cfg:
--------------------------------------------------------------------------------
1 | // CSBans MySQL database host address
2 | // -
3 | // Default: "127.0.0.1"
4 | ca_storage_host "127.0.0.1"
5 |
6 | // CSBans MySQL database user
7 | // -
8 | // Default: "root"
9 | ca_storage_user "root"
10 |
11 | // CSBans MySQL database host password
12 | // -
13 | // Default: ""
14 | ca_storage_pass ""
15 |
16 | // CSBans MySQL database name
17 | // -
18 | // Default: ""
19 | ca_storage_dbname ""
20 |
--------------------------------------------------------------------------------
/cstrike/addons/amxmodx/configs/plugins/ChatAdditions/CA_Storage_GameCMS.cfg:
--------------------------------------------------------------------------------
1 | // GameCMS MySQL database host address
2 | // -
3 | // Default: "127.0.0.1"
4 | ca_storage_host "127.0.0.1"
5 |
6 | // GameCMS MySQL database user
7 | // -
8 | // Default: "root"
9 | ca_storage_user "root"
10 |
11 | // GameCMS MySQL database host password
12 | // -
13 | // Default: ""
14 | ca_storage_pass ""
15 |
16 | // GameCMS MySQL database name
17 | // -
18 | // Default: ""
19 | ca_storage_dbname ""
20 |
--------------------------------------------------------------------------------
/cstrike/addons/amxmodx/configs/plugins/ChatAdditions/CA_Storage_PGBans.cfg:
--------------------------------------------------------------------------------
1 | // PGBans MySQL database host address
2 | // -
3 | // Default: "127.0.0.1"
4 | pgb_storage_host "127.0.0.1"
5 |
6 | // PGBans MySQL database user
7 | // -
8 | // Default: "root"
9 | pgb_storage_user "root"
10 |
11 | // PGBans MySQL database host password
12 | // -
13 | // Default: ""
14 | pgb_storage_pass ""
15 |
16 | // PGBans MySQL database name
17 | // -
18 | // Default: ""
19 | pgb_storage_dbname ""
20 |
--------------------------------------------------------------------------------
/cstrike/addons/amxmodx/configs/plugins/ChatAdditions/ChatAdditions_core.cfg:
--------------------------------------------------------------------------------
1 | // Log file type
2 | // 0 = log to common amxx log file (logs/L*.log)
3 | // 1 = log to plugins folder (logs/ChatAdditions/[plugin name]/*.log)
4 | // 2 = silent log to plugins folder (logs/%s/[plugin name]/L*.log)
5 | // -
6 | // Default: "1"
7 | // Minimum: "0.000000"
8 | // Maximum: "2.000000"
9 | ca_log_type "1"
10 |
11 | // Log level
12 | // 0 = disable logs
13 | // 1 = add info messages logs
14 | // 2 = add warinigs info
15 | // 3 = add debug messages
16 | // -
17 | // Default: "3"
18 | // Minimum: "0.000000"
19 | // Maximum: "3.000000"
20 | ca_log_level "1"
21 |
22 | // Enable update check?
23 | // 0 = disable update checks
24 | // -
25 | // Default: "1"
26 | // Minimum: "0.000000"
27 | // Maximum: "1.000000"
28 | ca_update_notify "1"
29 |
30 | // The time in days after which the log files should be deleted.
31 | // 0 - The logs won't be deleted.
32 | // > 0 - The logs will be deleted at the time inserted.
33 | // -
34 | // Default: "7"
35 | // Minimum: "0.000000"
36 | ca_log_autodelete_time "7"
37 |
--------------------------------------------------------------------------------
/cstrike/addons/amxmodx/configs/plugins/ChatAdditions/ca_gag_chat_whitelist_cmds.cfg:
--------------------------------------------------------------------------------
1 | // Usage: ca_gag_add_chat_whitelist_cmd
2 | // - a chat command that will be allowed to be executed even if the player is gagged
3 |
4 | ca_gag_add_chat_whitelist_cmd "/rs"
5 |
--------------------------------------------------------------------------------
/cstrike/addons/amxmodx/configs/plugins/ChatAdditions/ca_gag_reasons.cfg:
--------------------------------------------------------------------------------
1 | // Usage: ca_gag_add_reason [flags] [time]
2 | // - reason text message
3 | // [flags] - gag flags. (optional)
4 | // a = text chat, b = text team chat, c = voice chat
5 | // [time] - time in minutes (optional)
6 | // format: 1 = 1 second, 1i = 1 minute, 1h = 1 hour, 1d = 1 day, 1w = 1 week, 1m = 1 month, 1y = 1 year
7 | // Examples:
8 | // ca_gag_add_reason "Flood" "abc" "3h" - will add reason template with "Flood" reason, block all chat type, on 3 hours
9 | // ca_gag_add_reason "Flood" - will add reason template with "Flood" reason only
10 | //
11 | // NOTE: Set `time` or `flags` argument empty for allow to make your own choices.
12 | //
13 | // https://github.com/ChatAdditions/ChatAdditions_AMXX/wiki
14 |
15 | ca_gag_add_reason "Foul language / insults" "abc" ""
16 | ca_gag_add_reason "Flooding" "" "10i"
17 | ca_gag_add_reason "Monitoring" "abc" "10i"
18 | ca_gag_add_reason "Bad microphone" "c" "1h"
19 | ca_gag_add_reason "Chat ads" "ab" "1h"
20 | ca_gag_add_reason "Inappropriate behavior" "abc" "1d"
21 | ca_gag_add_reason "Microphone from 18+ age" "c" "1w"
22 |
--------------------------------------------------------------------------------
/cstrike/addons/amxmodx/data/lang/CA_Addon_DeathMute.txt:
--------------------------------------------------------------------------------
1 | [ru]
2 | DeathMute_ChatMessage = У Вас есть ^3%.0f сек^1, чтобы дать информацию тиммейтам, далее живые Вас ^3не услышат^1.
3 | DeathMute_YouMuted = Живые игроки Вас ^3не слышат^1.
4 | DeathMute_prefix = [^3Death mute^1]
5 |
6 | [en]
7 | DeathMute_ChatMessage = You have ^3%.0f seconds^1 to give information to your teammates, then the living ^3will not hear you^1.
8 | DeathMute_YouMuted = Live players ^3can't hear you^1.
9 | DeathMute_prefix = [^3Death mute^1]
10 |
11 | [es]
12 | DeathMute_ChatMessage = Tienes ^3%.0f segundos^1, para comunicarte con el equipo, después de eso tu equipo no ^3te oirá más^1.
13 | DeathMute_YouMuted = Jugadores vivos ^3no pueden oírte^1.
14 | DeathMute_prefix = [^3Death mute^1]
15 |
16 | [de]
17 | DeathMute_ChatMessage = ^3%.0f Sekunden^1 für die Team-Kommunikation, anschliessend kann Dich ^3niemand mehr hören^1.
18 | DeathMute_YouMuted = Lebende Spieler können Dich ^3nicht hören^1.
19 | DeathMute_prefix = [^3Death mute^1]
20 |
21 | [pl]
22 | DeathMute_ChatMessage = Masz ^3%.0f sekund^1 na podanie informacji kolegom z druzyny, ^3pozniej Cie nie uslysza.^1.
23 | DeathMute_YouMuted = Zywi gracze Cie^3 nie slysza^1.
24 | DeathMute_prefix = [^3Death mute^1]
25 |
26 | [ua]
27 | DeathMute_ChatMessage = У Вас є ^3%.0f сек^1, щоб надати інформацію тіммейтам, далі живі Вас ^3не почують^1.
28 | DeathMute_YouMuted = Живі гравці Вас ^3не чують^1.
29 | DeathMute_prefix = [^3Death mute^1]
30 |
31 | [ro]
32 | DeathMute_ChatMessage = Ai la dispozitie ^3%.0f secunde^1 sa le dai informatii coechipierilor, dupa aceea, cei vii ^3nu te vor mai auzi^1.
33 | DeathMute_YouMuted = Jucatorii in viata ^3nu te pot auzi^1.
34 | DeathMute_prefix = [^3Mut celor morti^1]
--------------------------------------------------------------------------------
/cstrike/addons/amxmodx/data/lang/CA_Addon_RankRestrictions.txt:
--------------------------------------------------------------------------------
1 | [ru]
2 | RankRestrictions_Warning_MinLevel = ^4* ^1Доступ к чату запрещен! Необходимо получить ^4%i ^1уровень.
3 | RankRestrictions_Warning_MinKills = ^4* ^1Доступ к чату запрещен! Необходимо убить ^4%i ^1противников.
4 |
5 | [en]
6 | RankRestrictions_Warning_MinLevel = ^4* ^1Chat access denied! It is necessary to get ^4%i ^1level.
7 | RankRestrictions_Warning_MinKills = ^4* ^1Chat access denied! You must kill ^4%i ^1opponents.
8 |
9 | [ua]
10 | RankRestrictions_Warning_MinLevel = ^4* ^1Доступ до чату заборонений! Необхідно отримати ^4%i ^1рівень.
11 | RankRestrictions_Warning_MinKills = ^4* ^1Доступ до чату заборонений! Необхідно вбити ^4%i ^1супротивників.
12 |
13 | [ro]
14 | RankRestrictions_Warning_MinLevel = ^4* ^1Accesul la chat este interzis! Ai nevoie de nivelul ^4%i^1.
15 | RankRestrictions_Warning_MinKills = ^4* ^1Accesul la chat este interzis! Trebuie sa ucizi ^4%i ^1inamici.
--------------------------------------------------------------------------------
/cstrike/addons/amxmodx/data/lang/CA_Addon_RequestUngag.txt:
--------------------------------------------------------------------------------
1 | [ru]
2 | RequestUnGag_NoAccess = ^4* ^1У вас не заблокирован чат.
3 | RequestUnGag_TimeOut = ^4* ^1Попробуйте через %i сек.
4 | RequestUnGag_Requested = ^4* ^1Игрок ^4%n ^1просит снять гаг. Чтобы снять гаг, напишите: ^4/ungag %d^1.
5 | RequestUnGag_YouRequested = ^4* ^1Вы попросили снять гаг.
6 |
7 | [en]
8 | RequestUnGag_NoAccess = ^4* ^1You don't have a chat block.
9 | RequestUnGag_TimeOut = ^4* ^1Try it in %i seconds.
10 | RequestUnGag_Requested = ^4* ^1The player ^4%n ^1asks to remove the gag. To remove it write: ^4/ungag %i^1.
11 | RequestUnGag_YouRequested = ^4* ^1You asked to take off the gag.
12 |
13 | [ro]
14 | RequestUnGag_NoAccess = ^4* ^1Chat-ul tau nu este blocat.
15 | RequestUnGag_TimeOut = ^4* ^1Incearca-l in %i secunde.
16 | RequestUnGag_Requested = ^4* ^1Jucatorul ^4%n ^1cere permisiunea de a i se inlatura gag-ul. Pentru a-i scoate gag-ul scrie: ^4/ungag %i^1.
17 | RequestUnGag_YouRequested = ^4* ^1Ai cerut permisiunea de a ti se inlatura gag-ul.
--------------------------------------------------------------------------------
/cstrike/addons/amxmodx/data/lang/CA_AntiFlood.txt:
--------------------------------------------------------------------------------
1 | [en]
2 | CA_ANTIFLOOD_CHAT_PREFIX = ^1[^4AntiFlood^1]
3 |
4 | CA_ANTIFLOOD_CHAT_STOP_FLOODING = ^1Stop ^3flooding.
5 | CA_ANTIFLOOD_CHAT_EQUAL_MESSAGE = ^1Your message ^3is repeated! ^4Exercise your imagination^1.
6 |
7 | [ru]
8 | CA_ANTIFLOOD_CHAT_PREFIX = ^1[^4AntiFlood^1]
9 |
10 | CA_ANTIFLOOD_CHAT_STOP_FLOODING = ^1Прекратите ^3флудить.
11 | CA_ANTIFLOOD_CHAT_EQUAL_MESSAGE = ^1Сообщение ^3повторяется! ^4Проявите фантазию^1.
12 |
13 | [ro]
14 | CA_ANTIFLOOD_CHAT_PREFIX = ^1[^4AntiFlood^1]
15 |
16 | CA_ANTIFLOOD_CHAT_STOP_FLOODING = ^1Opreste-te din ^3flood.
17 | CA_ANTIFLOOD_CHAT_EQUAL_MESSAGE = ^1Mesajul tau ^3se repeta! ^4Exerseaza-ti imaginatia^1.
--------------------------------------------------------------------------------
/cstrike/addons/amxmodx/data/lang/CA_Gag.txt:
--------------------------------------------------------------------------------
1 | [ru]
2 | Gag_MenuTitle_PlayersList = Заглушить игрока
3 | Gag_MenuTitle_SelectReason = Выберите причину:
4 | Gag_MenuTitle_SelectTime = Выберите время для заглушки:
5 | Gag_MenuItem_RemoveGag = \rСнять\w
6 | Gag_MenuItem_EditGag = Редактировать
7 | Gag_MenuItem_ShowGag = Заглушка игрока [\r%s\y]:
8 | Gag_MenuItem_PropSay = Чат:
9 | Gag_MenuItem_PropSayTeam = Командный чат:
10 | Gag_MenuItem_PropVoice = Голосовое общение:
11 | Gag_MenuItem_Time = Время:
12 | Gag_MenuItem_Confirm = Подтвердить!
13 | Gag_MenuItem_Reason = Причина:
14 | Gag_MenuItem_Resolution = Время: \y%s\w (причина: \y%s\w)
15 | Gag_MenuItem_Admin = Назначил:
16 | Gag_MenuItem_Type = Тип:
17 | Gag_MenuItem_Length = Длительность:
18 | Gag_MenuItem_Expire = Истекает:
19 | Gag_MenuItem_Left = Осталось:
20 |
21 | Gag_SelectFlags = Параметры заглушки игрока: [ \r%n\y ]
22 | Gag_EnterReason = Ввести свою ->\n
23 | Gag_EnterTime = Указать время ->
24 |
25 | Gag_Immunity = Иммунитет
26 | Gag_Gagged = *МОЛЧУН*
27 |
28 | Gag_ChatMsg_Reason = ^4Причина:^1
29 | Gag_NotSet = Не задано
30 | Gag_Permanent = *НАВСЕГДА*
31 |
32 | Gag_AdminGagPlayer = ^3заглушил ^1игрока ^4%s^1
33 | Gag_AdminUngagPlayer = ^3снял ^1заглушку с игрока ^4%s^1
34 | Gag_PlayerNotConnected = ^3Игрок недоступен!^1
35 | Gag_PlayerAlreadyRemoved = ^3Игрок ^4%n^1 уже удалён!^1
36 | Gag_PlayerExpiredGag = ^3У игрока ^4%n^1 истекло время заглушки.
37 |
38 | Gag_NotEnoughPlayers = ^3Недостаточно игроков, чтобы открыть меню!
39 | Gag_NoTemplatesAvailable_Reasons = ^3Нет шаблонов выбора причин.
40 | Gag_NoTemplatesAvailable_Times = ^3Нет шаблонов выбора времени.
41 |
42 | Gag_YouSetManual_Time = ^3Вы установили своё время:^1
43 | Gag_YouSetManual_Reason = ^3Вы установили причину заглушки:^1
44 | Gag_NotValidTimeEntered = ^3Время указано неверно:^1
45 |
46 | Gag_NotifyPlayer_BlockedChat = ^1Вам ^3заблокировали чат^1.
47 |
48 | Gag_prefix = [^3GAG^1]
49 |
50 | Gag_BackToPlayersMenu = К списку игроков
51 |
52 | [en]
53 | Gag_MenuTitle_PlayersList = Gag player
54 | Gag_MenuTitle_SelectReason = Choose reason:
55 | Gag_MenuTitle_SelectTime = Choose gag time:
56 | Gag_MenuItem_RemoveGag = \rRemove\w
57 | Gag_MenuItem_EditGag = Edit
58 | Gag_MenuItem_ShowGag = Player gag [\r%s\y]:
59 | Gag_MenuItem_PropSay = Chat:
60 | Gag_MenuItem_PropSayTeam = Team chat:
61 | Gag_MenuItem_PropVoice = Voice chat:
62 | Gag_MenuItem_Time = Time:
63 | Gag_MenuItem_Confirm = Confirm!
64 | Gag_MenuItem_Reason = Reason:
65 | Gag_MenuItem_Resolution = Time: \y%s\w (reason: \y%s\w)
66 | Gag_MenuItem_Admin = Admin:
67 | Gag_MenuItem_Type = Type:
68 | Gag_MenuItem_Length = Duration:
69 | Gag_MenuItem_Expire = Expire at:
70 | Gag_MenuItem_Left = Left:
71 |
72 | Gag_SelectFlags = Gag parameters: [ \r%n\y ]
73 | Gag_EnterReason = Enter gag reason ->\n
74 | Gag_EnterTime = Enter gag time ->
75 |
76 | Gag_Immunity = Gag_Immunity
77 | Gag_Gagged = *GAG*
78 |
79 | Gag_ChatMsg_Reason = ^4Reason:^1
80 | Gag_NotSet = Not selected
81 | Gag_Permanent = *PERMANENT*
82 |
83 | Gag_AdminGagPlayer = ^3gag ^1player ^4%s^1
84 | Gag_AdminUngagPlayer = ^3remove ^1gag from player ^4%s^1
85 | Gag_PlayerNotConnected = ^3Player not connected!
86 | Gag_PlayerAlreadyRemoved = ^3Player ^4%n^1 already removed!^1
87 | Gag_PlayerExpiredGag = ^3Player ^4%n^1 has expired gag.
88 |
89 | Gag_NotEnoughPlayers = ^3Not enough players to open menu!
90 | Gag_NoTemplatesAvailable_Reasons = No have reasons templates.
91 | Gag_NoTemplatesAvailable_Times = No have time templates.
92 |
93 | Gag_YouSetManual_Time = ^3You set custom time:^1
94 | Gag_YouSetManual_Reason = ^3You set custom reason:^1
95 | Gag_NotValidTimeEntered = ^3Entered time not valid:^1
96 |
97 | Gag_NotifyPlayer_BlockedChat = ^1Your ^3chat has been blocked^1.
98 |
99 | Gag_prefix = [^3GAG^1]
100 |
101 | Gag_BackToPlayersMenu = To players list
102 |
103 | [es]
104 | Gag_MenuTitle_PlayersList = Silenciar Jugador
105 | Gag_MenuTitle_SelectReason = Elegir Motivo:
106 | Gag_MenuTitle_SelectTime = Elegir Tiempo:
107 | Gag_MenuItem_RemoveGag = \rQuitar\w
108 | Gag_MenuItem_EditGag = Editar
109 | Gag_MenuItem_ShowGag = Jugador Silenciado [\r%s\y]:
110 | Gag_MenuItem_PropSay = Chat:
111 | Gag_MenuItem_PropSayTeam = Team Chat:
112 | Gag_MenuItem_PropVoice = Voz Chat:
113 | Gag_MenuItem_Time = Tiempo:
114 | Gag_MenuItem_Confirm = Confirmar!
115 | Gag_MenuItem_Reason = Motivo:
116 | Gag_MenuItem_Resolution = Tiempo: \y%s\w (Motivo: \y%s\w)
117 | Gag_MenuItem_Admin = Admin:
118 | Gag_MenuItem_Type = Tipo:
119 | Gag_MenuItem_Length = Duracion:
120 | Gag_MenuItem_Expire = Expira:
121 | Gag_MenuItem_Left = Restante:
122 |
123 | Gag_GagProperties = Parametros Silencio: [ \r%n\y ]
124 | Gag_EnterReason = Ingresar Motivo ->\n
125 | Gag_EnterTime = Ingresar Tiempo->
126 |
127 | Gag_Immunity = Inmunidad
128 | Gag_Gagged = Silenciado
129 |
130 | Gag_ChatMsg_Reason = ^4Motivo:^1
131 | Gag_NotSet = No Definido
132 | Gag_Permanent = Permanente
133 |
134 | Gag_AdminGagPlayer = ^3silencio ^1a jugador ^4%s^1
135 | Gag_AdminUngagPlayer = ^3quito ^1silencio a jugador ^4%s^1
136 | Gag_PlayerNotConnected = ^3Jugador no conectado!
137 | Gag_PlayerAlreadyRemoved = ^3Jugador ^4%n^1 ya quitado!^1
138 | Gag_PlayerExpiredGag = ^3Jugador ^4%n^1 ha expirado el silencio.
139 |
140 | Gag_NotEnoughPlayers = ^3No hay suficiente jugadores!
141 | Gag_NoTemplatesAvailable_Reasons = No hay plantillas de motivos.
142 | Gag_NoTemplatesAvailable_Times = No hay plantillas de tiempo.
143 |
144 | Gag_YouSetManual_Time = ^3Tiempo Personalizado:^1
145 | Gag_YouSetManual_Reason = ^3Motivo Personalizado:^1
146 | Gag_NotValidTimeEntered = ^3Tiempo ingresado no es valido:^1
147 |
148 | Gag_NotifyPlayer_BlockedChat = ^1Tu ^3chat ha sido bloqueado^1.
149 |
150 | Gag_prefix = [^3GAG^1]
151 |
152 | [de]
153 | Gag_MenuTitle_PlayersList = Spieler stummschalten
154 | Gag_MenuTitle_SelectReason = Wählen einen Grund:
155 | Gag_MenuTitle_SelectTime = Wähle die Dauer:
156 | Gag_MenuItem_RemoveGag = \gEntfernen\w
157 | Gag_MenuItem_EditGag = Bearbeiten
158 | Gag_MenuItem_ShowGag = Muted Spieler [\r%s\y]:
159 | Gag_MenuItem_PropSay = Chat:
160 | Gag_MenuItem_PropSayTeam = Team Chat:
161 | Gag_MenuItem_PropVoice = Voice:
162 | Gag_MenuItem_Time = Dauer:
163 | Gag_MenuItem_Confirm = Bestätigen!
164 | Gag_MenuItem_Reason = Grund:
165 | Gag_MenuItem_Resolution = Dauer: \y%s\w (Grund: \y%s\w)
166 | Gag_MenuItem_Admin = Admin:
167 | Gag_MenuItem_Type = Typ:
168 | Gag_MenuItem_Length = Dauer:
169 | Gag_MenuItem_Expire = Läuft ab:
170 | Gag_MenuItem_Left = Verbleibend:
171 |
172 | Gag_SelectFlags = Mute-Parameter: [ \r%n\y ]
173 | Gag_EnterReason = Der Grund ist ->\n
174 | Gag_EnterTime = Dauer setzen ->
175 |
176 | Gag_Immunity = Immunität
177 | Gag_Gagged = Stummgeschaltet
178 |
179 | Gag_ChatMsg_Reason = ^4Grund:^1
180 | Gag_NotSet = N/A
181 | Gag_Permanent = Permanent
182 |
183 | Gag_AdminGagPlayer = ^3Mute ^4%s^1
184 | Gag_AdminUngagPlayer = ^3Mute ^1von ^4%s^1 aufheben
185 | Gag_PlayerNotConnected = ^3Spieler nicht verbunden!
186 | Gag_PlayerAlreadyRemoved = ^3Spieler ^4%n^1 bereits entfernt!
187 | Gag_PlayerExpiredGag = ^3Mute des Spielers ^4%n^1 abgelaufen.
188 |
189 | Gag_NotEnoughPlayers = ^3Nicht genug Spieler
190 | Gag_NoTemplatesAvailable_Reasons = ^3Keine Gründe vorhanden.
191 | Gag_NoTemplatesAvailable_Times = ^3Keine Dauer vorhanden.
192 |
193 | Gag_YouSetManual_Time = ^3Dauer:^1
194 | Gag_YouSetManual_Reason = ^3Grund für Muten:^1
195 | Gag_NotValidTimeEntered = ^3Die Dauer stimmt nicht:^1
196 |
197 | Gag_NotifyPlayer_BlockedChat = ^1Dein ^3Chat wurde blockeriert^1.
198 |
199 | Gag_prefix = [^3GAG^1]
200 |
201 | [pl]
202 | Gag_MenuTitle_PlayersList = Zgaguj gracza
203 | Gag_MenuTitle_SelectReason = Wybrany gracz:
204 | Gag_MenuTitle_SelectTime = Wybierz czas:
205 | Gag_MenuItem_RemoveGag = \rUsun\w
206 | Gag_MenuItem_EditGag = Edytuj
207 | Gag_MenuItem_ShowGag = Zgagowany gracz [\r%s\y]:
208 | Gag_MenuItem_PropSay = Czat:
209 | Gag_MenuItem_PropSayTeam = Team czat:
210 | Gag_MenuItem_PropVoice = Voice czat:
211 | Gag_MenuItem_Time = Czas:
212 | Gag_MenuItem_Confirm = Potwierdz!
213 | Gag_MenuItem_Reason = Powod:
214 | Gag_MenuItem_Resolution = Czas:\y %s\w (powod:\y %s\w)
215 | Gag_MenuItem_Admin = Admin:
216 | Gag_MenuItem_Type = Typ:
217 | Gag_MenuItem_Length = Czas trwania:
218 | Gag_MenuItem_Expire = Wygasa:
219 | Gag_MenuItem_Left = Pozostalo:
220 |
221 | Gag_SelectFlags = Flagi gagowania: [\r %n\y]
222 | Gag_EnterReason = Podaj powod gaga ->\n
223 | Gag_EnterTime = Podaj czas gaga ->
224 |
225 | Gag_Immunity = Immunitet
226 | Gag_Gagged = *GAG*
227 |
228 | Gag_ChatMsg_Reason = ^4Powod:^1
229 | Gag_NotSet = Nie wybrano
230 | Gag_Permanent = permanentny
231 |
232 | Gag_AdminGagPlayer = ^3Zgagowany ^1gracz ^4%s^1
233 | Gag_AdminUngagPlayer = ^3Odgagowal ^1gracza ^4%s^1
234 | Gag_PlayerNotConnected = ^3Gracz nie jest polaczony!
235 | Gag_PlayerAlreadyRemoved = ^3Gracz ^4%n^1 zostal juz usuniety!^1
236 | Gag_PlayerExpiredGag = ^3Graczowi ^4%n^1 wlasnie wygasla blokada.
237 |
238 | Gag_NotEnoughPlayers = ^4Na serwerze nie ma nikogo^1, kogo bys mogl zgagowac!
239 | Gag_NoTemplatesAvailable_Reasons = Brak powodow
240 | Gag_NoTemplatesAvailable_Times = Brak czasow.
241 |
242 | Gag_YouSetManual_Time = ^4Ustawiles wlasny czas:^3
243 | Gag_YouSetManual_Reason = ^3Ustawiles wlasny powod:^3
244 | Gag_NotValidTimeEntered = ^3Wprowadzony czas jest nieprawidlowy:^1
245 |
246 | Gag_NotifyPlayer_BlockedChat = ^3Zostales zgagowany^1.
247 |
248 | Gag_prefix = [^3GAG^1]
249 |
250 | [ua]
251 | Gag_MenuTitle_PlayersList = Заглушити гравця
252 | Gag_MenuTitle_SelectReason = Оберіть причину:
253 | Gag_MenuTitle_SelectTime = Оберіть час для заглушки:
254 | Gag_MenuItem_RemoveGag = \rЗняти\w
255 | Gag_MenuItem_EditGag = Редагувати
256 | Gag_MenuItem_ShowGag = Заглушка гравця [\r%s\y]:
257 | Gag_MenuItem_PropSay = Чат:
258 | Gag_MenuItem_PropSayTeam = Командний чат:
259 | Gag_MenuItem_PropVoice = Голосове спілкування:
260 | Gag_MenuItem_Time = Час:
261 | Gag_MenuItem_Confirm = Підтвердити!
262 | Gag_MenuItem_Reason = Причина:
263 | Gag_MenuItem_Resolution = Час: \y%s\w (причина: \y%s\w)
264 | Gag_MenuItem_Admin = Призначив:
265 | Gag_MenuItem_Type = Тип:
266 | Gag_MenuItem_Length = Тривалість:
267 | Gag_MenuItem_Expire = Спливає:
268 | Gag_MenuItem_Left = Залишилося:
269 |
270 | Gag_SelectFlags = Параметри заглушки гравця: [ \r%n\y ]
271 | Gag_EnterReason = Ввести свою ->\n
272 | Gag_EnterTime = Вказати час ->
273 |
274 | Gag_Immunity = Іммунітет
275 | Gag_Gagged = *МОЛЧУН*
276 |
277 | Gag_ChatMsg_Reason = ^4Причина:^1
278 | Gag_NotSet = Не задано
279 | Gag_Permanent = *НАЗАВЖДИ*
280 |
281 | Gag_AdminGagPlayer = ^3заглушив ^1гравця ^4%s^1
282 | Gag_AdminUngagPlayer = ^3зняв ^1заглушку із гравця ^4%s^1
283 | Gag_PlayerNotConnected = ^3Гравець недоступний!^1
284 | Gag_PlayerAlreadyRemoved = ^3Гравець ^4%n^1 вже видалений!^1
285 | Gag_PlayerExpiredGag = ^3У гравця ^4%n^1 сплив час заглушки.
286 |
287 | Gag_NotEnoughPlayers = ^3Недостатньо гравців, щоб відкрити меню!
288 | Gag_NoTemplatesAvailable_Reasons = ^3Не має шаблонів вибору причин.
289 | Gag_NoTemplatesAvailable_Times = ^3Не має шаблонів вибору часу.
290 |
291 | Gag_YouSetManual_Time = ^3Ви встановили свій час:^1
292 | Gag_YouSetManual_Reason = ^3Ви встановили причину заглушки:^1
293 | Gag_NotValidTimeEntered = ^3Час вказаний невірно:^1
294 |
295 | Gag_NotifyPlayer_BlockedChat = ^1Вам ^1заблокували чат^1.
296 |
297 | Gag_prefix = [^3GAG^1]
298 |
299 | [ro]
300 | Gag_MenuTitle_PlayersList = Gag unui jucator
301 | Gag_MenuTitle_SelectReason = Alege motivul:
302 | Gag_MenuTitle_SelectTime = Alege timpul gag-ului:
303 | Gag_MenuItem_RemoveGag = \rInlatura\w
304 | Gag_MenuItem_EditGag = Editeaza
305 | Gag_MenuItem_ShowGag = Jucatorul cu gag [\r%s\y]:
306 | Gag_MenuItem_PropSay = Chat:
307 | Gag_MenuItem_PropSayTeam = Chat Echipa:
308 | Gag_MenuItem_PropVoice = Chat vocal:
309 | Gag_MenuItem_Time = Timp:
310 | Gag_MenuItem_Confirm = Confirma!
311 | Gag_MenuItem_Reason = Motiv:
312 | Gag_MenuItem_Resolution = Timp: \y%s\w (motiv: \y%s\w)
313 | Gag_MenuItem_Admin = Admin:
314 | Gag_MenuItem_Type = Tip:
315 | Gag_MenuItem_Length = Durata:
316 | Gag_MenuItem_Expire = Expira la:
317 | Gag_MenuItem_Left = Ramas:
318 |
319 | Gag_SelectFlags = Parametrii gag: [ \r%n\y ]
320 | Gag_EnterReason = Insereaza motivul gag-ului ->\n
321 | Gag_EnterTime = Insereaza timpul gag-ului ->
322 |
323 | Gag_Immunity = Imunitate_Gag
324 | Gag_Gagged = *GAG*
325 |
326 | Gag_ChatMsg_Reason = ^4Motiv:^1
327 | Gag_NotSet = Neselectat
328 | Gag_Permanent = *PERMANENT*
329 |
330 | Gag_AdminGagPlayer = ^3gag ^1jucatorul ^4%s^1
331 | Gag_AdminUngagPlayer = ^3inlaturare ^1gag jucatorului ^4%s^1
332 | Gag_PlayerNotConnected = ^3Jucatorul nu este conectat!
333 | Gag_PlayerAlreadyRemoved = ^3Jucatorul ^4%n^1 deja inlaturat!^1
334 | Gag_PlayerExpiredGag = ^3Jucaotrului ^4%n^1 i-a expirat gag-ul.
335 |
336 | Gag_NotEnoughPlayers = ^3Nu sunt suficienti jucatori pentru a deschide meniul!
337 | Gag_NoTemplatesAvailable_Reasons = Nu exista sabloane pentru motive.
338 | Gag_NoTemplatesAvailable_Times = Nu exista sabloane pentru timp.
339 |
340 | Gag_YouSetManual_Time = ^3Ai setat timpul personalizat:^1
341 | Gag_YouSetManual_Reason = ^3Ai setat motivul personalizat:^1
342 | Gag_NotValidTimeEntered = ^3Timpul inserat nu este valid:^1
343 |
344 | Gag_NotifyPlayer_BlockedChat = ^3Chat-ul ^1tau a fost ^4blocat^1.
345 |
346 | Gag_prefix = [^3GAG^1]
--------------------------------------------------------------------------------
/cstrike/addons/amxmodx/data/lang/CA_Mute.txt:
--------------------------------------------------------------------------------
1 | [ru]
2 | Mute_MenuTitle = Заглушить игрока:
3 | Mute_MuteAll = Заглушить всех
4 |
5 | Mute_YouMutePlayer = Вы НЕ слышите игрока
6 | Mute_YouUnmutePlayer = Вы снова слышите игрока
7 |
8 | Mute_NotEnoughPlayers = ^3Недостаточно игроков!
9 | Mute_PlayerNotConnected = ^3Игрок не подключен!
10 |
11 | Mute_PlayerMutedYou = Не слышит Вас
12 |
13 | Mute_PlayerNowMutedYou = теперь НЕ слышит Вас.
14 | Mute_PlayerNowUnmutedYou = вновь слышит Вас.
15 |
16 | Mute_UseTooOften = ^3Вы используете слишком часто!
17 |
18 | Mute_PlayerNowMutedAll = теперь НЕ слышит никого!
19 | Mute_PlayerNowUnmutedAll = снова слышит всех.
20 |
21 | Mute_prefix = [^3MUTE^1]
22 |
23 | [en]
24 | Mute_MenuTitle = Players mute menu:
25 | Mute_MuteAll = Mute all
26 |
27 | Mute_YouMutePlayer = Now you can't hear the player
28 | Mute_YouUnmutePlayer = You hear the player again
29 |
30 | Mute_NotEnoughPlayers = ^3Not enough players!
31 | Mute_PlayerNotConnected = ^3Player not connected!
32 |
33 | Mute_PlayerMutedYou = Muted you
34 |
35 | Mute_PlayerNowMutedYou = CAN'T hear you now.
36 | Mute_PlayerNowUnmutedYou = can hear you now.
37 |
38 | Mute_UseTooOften = ^3You use very often!
39 |
40 | Mute_PlayerNowMutedAll = CAN'T hear anybody now!
41 | Mute_PlayerNowUnmutedAll = can hear anybody now.
42 |
43 | Mute_prefix = [^3MUTE^1]
44 |
45 | [es]
46 | Mute_MenuTitle = Menu de Muteo de Jugadores:
47 | Mute_MuteAll = Mutear a Todos
48 |
49 | Mute_YouMutePlayer = Ahora no podes oir a ese jugador.
50 | Mute_YouUnmutePlayer = Ahora podes oir a ese jugador.
51 |
52 | Mute_NotEnoughPlayers = No hay suficiente jugadores!
53 | Mute_PlayerNotConnected = ^3Jugador no esta conectado!
54 |
55 | Mute_PlayerMutedYou = Te Muteo
56 |
57 | Mute_PlayerNowMutedYou = No puede oirte.
58 | Mute_PlayerNowUnmutedYou = Ahora puede oirte.
59 |
60 | Mute_UseTooOften = ^3Espera unos segundos antes de volver a usar!
61 |
62 | Mute_PlayerNowMutedAll = Ahora no escuchas a nadie.
63 | Mute_PlayerNowUnmutedAll = Ahora podes escuchar a todos.
64 |
65 | Mute_prefix = [^3MUTE^1]
66 |
67 | [de]
68 | Mute_MenuTitle = Spieler muten:
69 | Mute_MuteAll = Alle muten
70 |
71 | Mute_YouMutePlayer = Der Spieler ist gemuted
72 | Mute_YouUnmutePlayer = Du kannst den Spieler wieder hören
73 |
74 | Mute_NotEnoughPlayers = ^3Nicht genug Spieler!
75 | Mute_PlayerNotConnected = ^3Spieler nicht verbunden!
76 |
77 | Mute_PlayerMutedYou = hat Dich gemuted
78 |
79 | Mute_PlayerNowMutedYou = hat Dich jetzt gemuted.
80 | Mute_PlayerNowUnmutedYou = kann Dich wieder hören.
81 |
82 | Mute_UseTooOften = ^3Warte ein paar Sekunden!
83 |
84 | Mute_PlayerNowMutedAll = Du hörst NIEMANDEN!
85 | Mute_PlayerNowUnmutedAll = Du hörst ALLE!
86 |
87 | Mute_prefix = [^3MUTE^1]
88 |
89 | [pl]
90 | Mute_MenuTitle = Menu mutowania graczy:
91 | Mute_MuteAll = Zmutuj wszystkich
92 |
93 | Mute_YouMutePlayer = Zmutowales
94 | Mute_YouUnmutePlayer = Odmutowales
95 |
96 | Mute_NotEnoughPlayers = ^4Brak graczy, ktorych mozesz zmutowac!
97 | Mute_PlayerNotConnected = ^3Gracz nie jest polaczony!
98 |
99 | Mute_PlayerMutedYou = Zmutowany
100 |
101 | Mute_PlayerNowMutedYou = Zmutowal Cie.
102 | Mute_PlayerNowUnmutedYou = Odmutowal Cie
103 |
104 | Mute_UseTooOften = ^3Bardzo czesto tego uzywasz
105 |
106 | Mute_PlayerNowMutedAll = Zmutowales wszystkich!
107 | Mute_PlayerNowUnmutedAll = Odmutowales wszystkich
108 |
109 | Mute_prefix = [^3MUTE^1]
110 |
111 | [ua]
112 | Mute_MenuTitle = Заглушити гравця:
113 | Mute_MuteAll = Заглушити всіх
114 |
115 | Mute_YouMutePlayer = Ви НЕ чуєте гравця
116 | Mute_YouUnmutePlayer = Ви знову чуєте гравця
117 |
118 | Mute_NotEnoughPlayers = ^3Недостатньо гравців!
119 | Mute_PlayerNotConnected = ^3Гравець не підключений!
120 |
121 | Mute_PlayerMutedYou = Не чує Вас
122 |
123 | Mute_PlayerNowMutedYou = тепер НЕ чує Вас.
124 | Mute_PlayerNowUnmutedYou = знову чує Вас.
125 |
126 | Mute_UseTooOften = ^3Ви використовуєте занадто часто!
127 |
128 | Mute_PlayerNowMutedAll = тепер НЕ чує нікого!
129 | Mute_PlayerNowUnmutedAll = знову чує всіх.
130 |
131 | Mute_prefix = [^3MUTE^1]
132 |
133 | [ro]
134 | Mute_MenuTitle = Meniul pentru mut al jucatorilor:
135 | Mute_MuteAll = Dezactiveaza tuturor
136 |
137 | Mute_YouMutePlayer = Nu mai auzi jucatorul
138 | Mute_YouUnmutePlayer = Auzi din nou jucatorul
139 |
140 | Mute_NotEnoughPlayers = ^3Nu sunt suficienti jucatori!
141 | Mute_PlayerNotConnected = ^3Jucatorul nu este conectat!
142 |
143 | Mute_PlayerMutedYou = Te-a restrictionat
144 |
145 | Mute_PlayerNowMutedYou = Nu te mai poate auzi.
146 | Mute_PlayerNowUnmutedYou = te poate auzi.
147 |
148 | Mute_UseTooOften = ^3Folosesti prea des!
149 |
150 | Mute_PlayerNowMutedAll = Nu poate auzi pe nimeni!
151 | Mute_PlayerNowUnmutedAll = poate sa ii auda pe toti.
152 |
153 | Mute_prefix = [^3MUTE^1]
--------------------------------------------------------------------------------
/cstrike/addons/amxmodx/scripting/ChatAdditions/Addons/CA_Addon_DeathMute.sma:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | #include
6 |
7 | #pragma tabsize 4
8 |
9 | new Float: ca_deathmute_time,
10 | bool: ca_deathmute_dead_hear_alive,
11 | NotifyType_s: ca_deathmute_notify_type,
12 | bool: ca_deathmute_notify_show_progressbar,
13 | Float: ca_deathmute_notify_hud_x,
14 | Float: ca_deathmute_notify_hud_y,
15 | ca_deathmute_notify_hud_r,
16 | ca_deathmute_notify_hud_g,
17 | ca_deathmute_notify_hud_b,
18 | ca_deathmute_immunity_flags[16]
19 |
20 | enum NotifyType_s: {
21 | notify_Disabled,
22 | notify_Chat,
23 | notify_HUD
24 | }
25 |
26 | new bool: g_canSpeakWithAlive[MAX_PLAYERS + 1]
27 |
28 | new g_syncHudOj
29 |
30 | public stock const PluginName[] = "CA Addon: Death mute"
31 | public stock const PluginVersion[] = CA_VERSION
32 | public stock const PluginAuthor[] = "Sergey Shorokhov"
33 | public stock const PluginURL[] = "https://github.com/ChatAdditions/"
34 | public stock const PluginDescription[] = "Alive players don't hear dead players after 5 secs"
35 |
36 | public plugin_init() {
37 | register_plugin(PluginName, PluginVersion, PluginAuthor)
38 |
39 | register_dictionary("CA_Addon_DeathMute.txt")
40 |
41 | Create_CVars()
42 |
43 | AutoExecConfig(true, "CA_Addon_DeathMute", "ChatAdditions")
44 |
45 | // RegisterHam(Ham_TFC_Killed, "player", "CBasePlayer_Killed", .Post = true) // Does it need ?!
46 | RegisterHam(Ham_Killed, "player", "CBasePlayer_Killed", .Post = true)
47 | RegisterHam(Ham_Spawn, "player", "CBasePlayer_Spawn", .Post = true)
48 |
49 | g_syncHudOj = CreateHudSyncObj()
50 | }
51 |
52 | Create_CVars() {
53 | bind_pcvar_float(create_cvar("ca_deathmute_time", "5.0",
54 | .description = "Time (in seconds) for killed players, during which they can report information to living players.^n\
55 | 0 - disabled functionality",
56 | .has_min = true, .min_val = 0.0,
57 | .has_max = true, .max_val = 240.0
58 | ), ca_deathmute_time
59 | )
60 |
61 | bind_pcvar_num(create_cvar("ca_deathmute_dead_hear_alive", "1",
62 | .description = "Death mute mode^n\
63 | 0 - alive hear only alive, dead hear all^n\
64 | 1 - alive hear only alive, dead hear only dead",
65 | .has_min = true, .min_val = 0.0,
66 | .has_max = true, .max_val = 1.0
67 | ), ca_deathmute_dead_hear_alive
68 | )
69 |
70 | bind_pcvar_num(create_cvar("ca_deathmute_notify_type", "1",
71 | .description = "Notification type for dead players ^n\
72 | 0 - disabled functionality^n\
73 | 1 - chat message^n\
74 | 2 - HUD message"
75 | ), ca_deathmute_notify_type
76 | )
77 |
78 | bind_pcvar_num(create_cvar("ca_deathmute_notify_show_progressbar", "1",
79 | .description = "Show progressbar ^n\
80 | 0 - disabled functionality"
81 | ), ca_deathmute_notify_show_progressbar
82 | )
83 |
84 | bind_pcvar_float(create_cvar("ca_deathmute_notify_hud_x", "-1.0",
85 | .description = "X position for HUD message^n\
86 | -1.0 - center",
87 | .has_min = true, .min_val = -1.0,
88 | .has_max = true, .max_val = 1.0
89 | ), ca_deathmute_notify_hud_x
90 | )
91 |
92 | bind_pcvar_float(create_cvar("ca_deathmute_notify_hud_y", "0.15",
93 | .description = "Y position for HUD message^n\
94 | -1.0 - center",
95 | .has_min = true, .min_val = -1.0,
96 | .has_max = true, .max_val = 1.0
97 | ), ca_deathmute_notify_hud_y
98 | )
99 |
100 | bind_pcvar_num(create_cvar("ca_deathmute_notify_hud_r", "200",
101 | .description = "Red color value (in RGB) [0...255]",
102 | .has_min = true, .min_val = 0.0,
103 | .has_max = true, .max_val = 255.0
104 | ), ca_deathmute_notify_hud_r
105 | )
106 |
107 | bind_pcvar_num(create_cvar("ca_deathmute_notify_hud_g", "50",
108 | .description = "Green color value (in RGB) [0...255]",
109 | .has_min = true, .min_val = 0.0,
110 | .has_max = true, .max_val = 255.0
111 | ), ca_deathmute_notify_hud_g
112 | )
113 |
114 | bind_pcvar_num(create_cvar("ca_deathmute_notify_hud_b", "0",
115 | .description = "Blue color value (in RGB) [0...255]",
116 | .has_min = true, .min_val = 0.0,
117 | .has_max = true, .max_val = 255.0
118 | ), ca_deathmute_notify_hud_b
119 | )
120 |
121 | bind_pcvar_string(create_cvar("ca_deathmute_immunity_flags", "a",
122 | .description = "User immunity flag"
123 | ),
124 | ca_deathmute_immunity_flags, charsmax(ca_deathmute_immunity_flags)
125 | )
126 | }
127 |
128 | public client_disconnected(id) {
129 | g_canSpeakWithAlive[id] = false
130 |
131 | remove_task(id)
132 | }
133 |
134 | public CBasePlayer_Spawn(const id) {
135 | if (!is_user_alive(id))
136 | return
137 |
138 | g_canSpeakWithAlive[id] = true
139 |
140 | remove_task(id)
141 | }
142 |
143 | public CBasePlayer_Killed(const id, const attacker) {
144 | if (ca_deathmute_time <= 0.0) {
145 | return
146 | }
147 |
148 | set_task_ex(ca_deathmute_time, "DisableSpeakWithAlive", .id = id)
149 |
150 | switch (ca_deathmute_notify_type) {
151 | case notify_Disabled: return
152 |
153 | case notify_Chat: client_print_color(id, print_team_red, "%L %L", id, "DeathMute_prefix", id, "DeathMute_ChatMessage", ca_deathmute_time)
154 |
155 | case notify_HUD: {
156 | set_hudmessage(
157 | ca_deathmute_notify_hud_r,
158 | ca_deathmute_notify_hud_g,
159 | ca_deathmute_notify_hud_b,
160 | ca_deathmute_notify_hud_x,
161 | ca_deathmute_notify_hud_y,
162 | .fadeouttime = 0.0,
163 | .holdtime = ca_deathmute_time - 1.0
164 | )
165 |
166 | static clearedMessage[256]
167 |
168 | formatex(clearedMessage, charsmax(clearedMessage), "%L", id, "DeathMute_ChatMessage", ca_deathmute_time)
169 | ReplaceColors(clearedMessage, charsmax(clearedMessage))
170 |
171 | ShowSyncHudMsg(id, g_syncHudOj, clearedMessage)
172 | }
173 | }
174 |
175 | if (ca_deathmute_notify_show_progressbar) {
176 | UTIL_BarTime(id, floatround(ca_deathmute_time))
177 | }
178 | }
179 |
180 | public DisableSpeakWithAlive(const id) {
181 | g_canSpeakWithAlive[id] = false
182 |
183 | switch (ca_deathmute_notify_type) {
184 | case notify_Chat: client_print_color(id, print_team_red, "%L %L", id, "DeathMute_prefix", id, "DeathMute_YouMuted")
185 |
186 | case notify_HUD: {
187 | set_hudmessage(
188 | ca_deathmute_notify_hud_r,
189 | ca_deathmute_notify_hud_g,
190 | ca_deathmute_notify_hud_b,
191 | ca_deathmute_notify_hud_x,
192 | ca_deathmute_notify_hud_y,
193 | .fadeouttime = 0.0,
194 | .holdtime = ca_deathmute_time - 1.0
195 | )
196 |
197 | static clearedMessage[256]
198 |
199 | formatex(clearedMessage, charsmax(clearedMessage), "%L", id, "DeathMute_YouMuted", ca_deathmute_time)
200 | ReplaceColors(clearedMessage, charsmax(clearedMessage))
201 |
202 | ShowSyncHudMsg(id, g_syncHudOj, clearedMessage)
203 | }
204 | }
205 | }
206 |
207 | public CA_Client_Voice(const listener, const sender) {
208 | if (ca_deathmute_time <= 0.0) {
209 | return CA_CONTINUE
210 | }
211 |
212 | new bool: listenerHasImmunity = bool: (get_user_flags(listener) & read_flags(ca_deathmute_immunity_flags))
213 |
214 | if (listenerHasImmunity) {
215 | return CA_CONTINUE
216 | }
217 |
218 | new bool: listenerAlive = bool: is_user_alive(listener)
219 | new bool: senderAlive = bool: is_user_alive(sender)
220 |
221 | if (!g_canSpeakWithAlive[sender] && !senderAlive && listenerAlive) {
222 | return CA_SUPERCEDE
223 | }
224 |
225 | if (!ca_deathmute_dead_hear_alive && !listenerAlive && senderAlive) {
226 | return CA_SUPERCEDE
227 | }
228 |
229 | return CA_CONTINUE
230 | }
231 |
232 | stock ReplaceColors(text[], len)
233 | {
234 | replace_string(text, len, "^1", "")
235 | replace_string(text, len, "^3", "")
236 | replace_string(text, len, "^4", "")
237 | }
238 |
--------------------------------------------------------------------------------
/cstrike/addons/amxmodx/scripting/ChatAdditions/Addons/CA_Addon_RankRestrictions.sma:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #tryinclude
4 |
5 | #include
6 |
7 | #pragma tabsize 4
8 |
9 | // Natives
10 | native aes_get_player_level(const player)
11 | native ar_get_user_level(const player, rankName[] = "", len = 0)
12 | native crxranks_get_user_level(const player)
13 | native cmsranks_get_user_level(player, level[] = "", len = 0)
14 | native csstats_get_user_stats(const player, const stats[22])
15 | native Float:cmsstats_get_user_skill(player, skillname[] = "", namelen = 0, &skill_level = 0)
16 | native get_user_skill(player, &Float: skill)
17 | native get_user_stats(player, stats[STATSX_MAX_STATS], bodyhits[MAX_BODYHITS])
18 | //
19 |
20 |
21 | enum any: eChatType {
22 | voice_chat,
23 | text_chat
24 | }
25 |
26 | enum any: eRankRestrictionsType {
27 | rr_type_none,
28 | rr_type_level,
29 | rr_type_frags
30 | }
31 |
32 | const Float: STATS_THINKER_FREQ = 30.0
33 |
34 | enum Stats_s {
35 | Stats_Level,
36 | Stats_Kills,
37 | Float: Stats_NextUpdate,
38 | }
39 |
40 | new g_playersStats[MAX_PLAYERS + 1][Stats_s]
41 |
42 | new ca_rankrestrictions_type,
43 | ca_rankrestrictions_type_kills,
44 | ca_rankrestrictions_min_kills_voice_chat,
45 | ca_rankrestrictions_min_kills_text_chat,
46 | ca_rankrestrictions_type_level,
47 | ca_rankrestrictions_min_level_voice_chat,
48 | ca_rankrestrictions_min_level_text_chat,
49 | ca_rankrestrictions_immunity_flag[16],
50 | ca_rankrestrictions_steam_immunity
51 |
52 | public stock const PluginName[] = "CA Addon: Rank restrictions"
53 | public stock const PluginVersion[] = CA_VERSION
54 | public stock const PluginAuthor[] = "steelzzz"
55 | public stock const PluginURL[] = "https://github.com/ChatAdditions/"
56 | public stock const PluginDescription[] = "Restrict chat until you reach the rank of a statistic"
57 |
58 | public plugin_init() {
59 | register_plugin(PluginName, PluginVersion, PluginAuthor)
60 | register_dictionary("CA_Addon_RankRestrictions.txt")
61 |
62 | Create_CVars()
63 |
64 | AutoExecConfig(true, "CA_Addon_RankRestrictions", "ChatAdditions")
65 | }
66 |
67 | public plugin_natives() {
68 | set_native_filter("native_filter")
69 | }
70 |
71 | public native_filter(const name[], index, trap) {
72 | new const na[][] = {
73 | "aes_get_player_level",
74 | "ar_get_user_level",
75 | "crxranks_get_user_level",
76 | "csstats_get_user_stats",
77 | "cmsranks_get_user_level",
78 | "cmsstats_get_user_skill",
79 | "get_user_stats"
80 | }
81 |
82 | for (new i; i < sizeof(na); i++) {
83 | if (strcmp(na[i], name) != 0)
84 | return PLUGIN_HANDLED
85 | }
86 |
87 | return PLUGIN_CONTINUE
88 | }
89 |
90 | Create_CVars() {
91 | bind_pcvar_num(create_cvar("ca_rankrestrictions_type", "1",
92 | .description = "Restrictions Type^n\
93 | 0 - Disable restrictions^n\
94 | 1 - Level restrictions^n\
95 | 2 - Kills count restrictions",
96 | .has_min = true, .min_val = 0.0,
97 | .has_max = true, .max_val = 2.0
98 | ), ca_rankrestrictions_type
99 | )
100 |
101 | bind_pcvar_num(create_cvar("ca_rankrestrictions_type_kills", "1",
102 | .description = "Kill System Types^n\
103 | 0 - CSStats MySQL^n\
104 | 1 - CSX Module",
105 | .has_min = true, .min_val = 0.0,
106 | .has_max = true, .max_val = 1.0
107 | ), ca_rankrestrictions_type_kills
108 | )
109 |
110 | bind_pcvar_num(create_cvar("ca_rankrestrictions_min_kills_voice_chat", "10",
111 | .description = "Min kills count to access VOICE chat",
112 | .has_min = true, .min_val = 0.0
113 | ), ca_rankrestrictions_min_kills_voice_chat
114 | )
115 |
116 | bind_pcvar_num(create_cvar("ca_rankrestrictions_min_kills_text_chat", "10",
117 | .description = "Min kills count to access TEXT chat",
118 | .has_min = true, .min_val = 0.0
119 | ), ca_rankrestrictions_min_kills_text_chat
120 | )
121 |
122 | bind_pcvar_num(create_cvar("ca_rankrestrictions_type_level", "1",
123 | .description = "Level System Types^n\
124 | 0 - Advanced Experience System^n\
125 | 1 - Army Ranks Ultimate^n\
126 | 2 - OciXCrom's Rank System^n\
127 | 3 - CMSStats Ranks^n\
128 | 4 - CMSStats MySQL^n\
129 | 5 - CSstatsX SQL^n\
130 | 6 - CSX Module",
131 | .has_min = true, .min_val = 0.0,
132 | .has_max = true, .max_val = 6.0
133 | ), ca_rankrestrictions_type_level
134 | )
135 |
136 | bind_pcvar_num(create_cvar("ca_rankrestrictions_min_level_voice_chat", "2",
137 | .description = "Min Level to access VOICE chat",
138 | .has_min = true, .min_val = 0.0
139 | ), ca_rankrestrictions_min_level_voice_chat
140 | )
141 |
142 | bind_pcvar_num(create_cvar("ca_rankrestrictions_min_level_text_chat", "2",
143 | .description = "Min Level to access TEXT chat",
144 | .has_min = true, .min_val = 0.0
145 | ), ca_rankrestrictions_min_level_text_chat
146 | )
147 |
148 | bind_pcvar_string(create_cvar("ca_rankrestrictions_immunity_flag", "a",
149 | .description = "User immunity flag"
150 | ),
151 | ca_rankrestrictions_immunity_flag, charsmax(ca_rankrestrictions_immunity_flag)
152 | )
153 |
154 | bind_pcvar_num(create_cvar("ca_rankrestrictions_steam_immunity", "0",
155 | .description = "Enable immunity for steam players",
156 | .has_min = true, .min_val = 0.0,
157 | .has_max = true, .max_val = 1.0
158 | ), ca_rankrestrictions_steam_immunity
159 | )
160 | }
161 |
162 | public client_putinserver(player) {
163 | Stats_Update(player)
164 | }
165 |
166 | public client_remove(player) {
167 | Stats_Update(player)
168 | }
169 |
170 | public CA_Client_Say(player, const bool: isTeamMessage, const message[]) {
171 | if (!CanCommunicate(player, true, text_chat)) {
172 | return CA_SUPERCEDE
173 | }
174 |
175 | return CA_CONTINUE
176 | }
177 |
178 | public CA_Client_Voice(const listener, const sender) {
179 | if (!CanCommunicate(sender, false, voice_chat)) {
180 | // need chat notification?
181 | return CA_SUPERCEDE
182 | }
183 |
184 | return CA_CONTINUE
185 | }
186 |
187 | bool: CanCommunicate(const player, const bool: print, chatType) {
188 | if (ca_rankrestrictions_type <= rr_type_none) {
189 | return true
190 | }
191 |
192 | // check is gagged?
193 | if (get_user_flags(player) & read_flags(ca_rankrestrictions_immunity_flag)) {
194 | return true
195 | }
196 |
197 | if (ca_rankrestrictions_steam_immunity && _is_user_steam(player)) {
198 | return true
199 | }
200 |
201 | switch (chatType) {
202 | case voice_chat: {
203 | if (ca_rankrestrictions_type == rr_type_level && g_playersStats[player][Stats_Level] < ca_rankrestrictions_min_level_voice_chat) {
204 | if (print) {
205 | client_print_color(player, print_team_red, "%L",
206 | player, "RankRestrictions_Warning_MinLevel", ca_rankrestrictions_min_level_voice_chat
207 | )
208 | }
209 |
210 | return false
211 | }
212 |
213 | if (ca_rankrestrictions_type == rr_type_frags && g_playersStats[player][Stats_Kills] < ca_rankrestrictions_min_kills_voice_chat) {
214 | if (print) {
215 | client_print_color(player, print_team_red, "%L",
216 | player, "RankRestrictions_Warning_MinKills", ca_rankrestrictions_min_kills_voice_chat
217 | )
218 | }
219 |
220 | return false
221 | }
222 | }
223 |
224 | case text_chat: {
225 | if (ca_rankrestrictions_type == rr_type_level && g_playersStats[player][Stats_Level] < ca_rankrestrictions_min_level_text_chat) {
226 | if (print) {
227 | client_print_color(player, print_team_red, "%L",
228 | player, "RankRestrictions_Warning_MinLevel", ca_rankrestrictions_min_level_text_chat
229 | )
230 | }
231 |
232 | return false
233 | }
234 |
235 | if (ca_rankrestrictions_type == rr_type_frags && g_playersStats[player][Stats_Kills] < ca_rankrestrictions_min_kills_text_chat) {
236 | if (print) {
237 | client_print_color(player, print_team_red, "%L",
238 | player, "RankRestrictions_Warning_MinKills", ca_rankrestrictions_min_kills_text_chat
239 | )
240 | }
241 |
242 | return false
243 | }
244 | }
245 | }
246 |
247 | return true
248 | }
249 |
250 | Stats_ReadUserLevel(const player) {
251 | switch (ca_rankrestrictions_type_level) {
252 | case 0: return aes_get_player_level(player)
253 | case 1: return ar_get_user_level(player)
254 | case 2: return crxranks_get_user_level(player)
255 | case 3: return cmsranks_get_user_level(player)
256 | case 4: {
257 | new iSkill
258 | cmsstats_get_user_skill(player, .skill_level = iSkill)
259 | return iSkill
260 | }
261 | case 5: {
262 | new Float:iSkill
263 | get_user_skill(player, iSkill)
264 | return floatround(iSkill)
265 | }
266 | case 6: {
267 | new stats[STATSX_MAX_STATS], hits[MAX_BODYHITS]
268 | get_user_stats(player, stats, hits)
269 | return stats[STATSX_RANK]
270 | }
271 | }
272 |
273 | return 0
274 | }
275 |
276 | Stats_ReadUserFrags(const player) {
277 | enum { stats_Frags/* , stats_Deaths, stats_Rounds = 16 */ }
278 |
279 | switch (ca_rankrestrictions_type_kills) {
280 | case 0: {
281 | new stats[22]
282 | csstats_get_user_stats(player, stats)
283 | return stats[stats_Frags]
284 | }
285 | case 1: {
286 | new stats[STATSX_MAX_STATS], hits[MAX_BODYHITS]
287 | get_user_stats(player, stats, hits)
288 | return stats[STATSX_KILLS]
289 | }
290 | }
291 |
292 | return 0
293 | }
294 |
295 | public Stats_Update(player) {
296 | if (!is_user_connected(player) || is_user_bot(player)) {
297 | g_playersStats[player][Stats_Level] = 0
298 | g_playersStats[player][Stats_Kills] = 0
299 | g_playersStats[player][Stats_NextUpdate] = 0.0
300 |
301 | remove_task(player)
302 | return
303 | }
304 |
305 | if (!task_exists(player))
306 | set_task_ex(STATS_THINKER_FREQ, "Stats_Update", .id = player, .flags = SetTask_Repeat)
307 |
308 | new Float: gametime = get_gametime()
309 | if (g_playersStats[player][Stats_NextUpdate] > gametime)
310 | return
311 |
312 | g_playersStats[player][Stats_Level] = Stats_ReadUserLevel(player)
313 | g_playersStats[player][Stats_Kills] = Stats_ReadUserFrags(player)
314 | g_playersStats[player][Stats_NextUpdate] = gametime + STATS_THINKER_FREQ
315 | }
316 |
317 | static stock bool: _is_user_steam(const player) {
318 | #if (defined _reapi_reunion_included)
319 | if (has_reunion())
320 | return (REU_GetAuthtype(player) == CA_TYPE_STEAM)
321 | #endif
322 |
323 | static dp_r_id_provider
324 | if (dp_r_id_provider || (dp_r_id_provider = get_cvar_pointer("dp_r_id_provider"))) {
325 | server_cmd("dp_clientinfo %i", player)
326 | server_exec()
327 |
328 | #define DP_AUTH_STEAM 2
329 | if (get_pcvar_num(dp_r_id_provider) == DP_AUTH_STEAM)
330 | return true
331 |
332 | return false
333 | }
334 |
335 | return false
336 | }
337 |
--------------------------------------------------------------------------------
/cstrike/addons/amxmodx/scripting/ChatAdditions/Addons/CA_Addon_RequestUnGag.sma:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include
5 | #include
6 |
7 | #pragma tabsize 4
8 |
9 | new Float: g_userNextRequestTime[MAX_PLAYERS + 1]
10 |
11 | new ca_requestungag_cmd[32],
12 | Float: ca_requestungag_delay,
13 | ca_gag_access_flags_high[32],
14 | ca_gag_access_flags[32]
15 |
16 | public stock const PluginName[] = "CA Addon: Request UnGAG"
17 | public stock const PluginVersion[] = CA_VERSION
18 | public stock const PluginAuthor[] = "steelzzz"
19 | public stock const PluginURL[] = "https://github.com/ChatAdditions/"
20 | public stock const PluginDescription[] = "A player can apologize to the administration"
21 |
22 | public plugin_init() {
23 | register_plugin(PluginName, PluginVersion, PluginAuthor)
24 | register_dictionary("CA_Addon_RequestUngag.txt")
25 |
26 | Create_CVars()
27 |
28 | AutoExecConfig(true, "CA_Addon_RequestUnGag", "ChatAdditions")
29 | }
30 |
31 | public Create_CVars() {
32 | bind_pcvar_string(create_cvar("ca_requestungag_cmd", "/sorry",
33 | .description = "Request ungag command"),
34 | ca_requestungag_cmd, charsmax(ca_requestungag_cmd)
35 | )
36 |
37 | bind_pcvar_float(create_cvar("ca_requestungag_delay", "40.0",
38 | .description = "delay time request ungag",
39 | .has_min = true, .min_val = 1.0),
40 | ca_requestungag_delay
41 | )
42 |
43 | bind_pcvar_string(get_cvar_pointer("ca_gag_access_flags_high"),
44 | ca_gag_access_flags_high, charsmax(ca_gag_access_flags_high)
45 | )
46 |
47 | bind_pcvar_string(get_cvar_pointer("ca_gag_access_flags"),
48 | ca_gag_access_flags, charsmax(ca_gag_access_flags)
49 | )
50 | }
51 |
52 | // TODO: Create `_PRE` hook forward instead this.
53 | public CA_Client_Say(player, const bool: isTeamMessage, const message[]) {
54 | if (strcmp(message, ca_requestungag_cmd) != 0)
55 | return CA_CONTINUE
56 |
57 | if (!ca_has_user_gag(player)) {
58 | client_print_color(player, print_team_default, "%L", player, "RequestUnGag_NoAccess")
59 |
60 | return CA_SUPERCEDE
61 | }
62 |
63 | new Float: gametime = get_gametime()
64 | if (g_userNextRequestTime[player] > gametime) {
65 | new timeLeft = floatround(g_userNextRequestTime[player] - gametime, floatround_ceil)
66 | client_print_color(player, print_team_default, "%L", player, "RequestUnGag_TimeOut", timeLeft)
67 |
68 | return CA_SUPERCEDE
69 | }
70 |
71 | new userID = get_user_userid(player)
72 |
73 | new players[MAX_PLAYERS], count
74 | get_players_ex(players, count, (GetPlayers_ExcludeBots | GetPlayers_ExcludeHLTV))
75 |
76 | new accessFlagsHigh = read_flags(ca_gag_access_flags_high)
77 | new accessFlags = read_flags(ca_gag_access_flags)
78 |
79 | for(new i; i < count; i++) {
80 | new receiver = players[i]
81 |
82 | if (receiver == player)
83 | continue
84 |
85 | if (!(get_user_flags(receiver) & (accessFlags | accessFlagsHigh)))
86 | continue
87 |
88 | client_print_color(receiver, print_team_default, "%L",
89 | receiver, "RequestUnGag_Requested",
90 | player, userID
91 | )
92 | }
93 |
94 | g_userNextRequestTime[player] = gametime + ca_requestungag_delay
95 |
96 | client_print_color(player, print_team_default, "%L", player, "RequestUnGag_YouRequested")
97 | return CA_SUPERCEDE
98 | }
99 |
--------------------------------------------------------------------------------
/cstrike/addons/amxmodx/scripting/ChatAdditions/Addons/CA_Addon_VoteGag.sma:
--------------------------------------------------------------------------------
1 | /*
2 | * The plugin is based on an existing plugin from UCC by neygomon.
3 | */
4 |
5 | #include
6 | #include
7 |
8 |
9 | /* ======== SETTINGS ======== */
10 | #define PREFIX "CA: VoteGAG" // Префикс сообщений в чате
11 | #define REPEAT_VOTE_MIN 2 // Частота повторных голосований
12 | #define PERCENT_VOTE_OK 60 // Процент голосов для успешного голосования
13 | #define BLOCK_TIME_MIN 3 // Время GAG'a игрока
14 | #define CHECK_VOTE_TIME 15.0 // Продолжительность голосования
15 | const IMMUNITY_FLAGS = ADMIN_IMMUNITY; // Иммунитет к функциям VoteGAG'а
16 | /* ======== LANG ======== */
17 | #define MSG_PLMENU_TITLE "\d[\rVoteGag\d] \yВыберите игрока"
18 | #define MSG_VMENU_TITLE "\d[\rVoteGag\d] \yЗаткнуть игрока \r%s\y?"
19 | #define MSG_MENU_YES "\rДа"
20 | #define MSG_MENU_NO "\yНет"
21 | #define MSG_MENU_NEXT "\yДалее"
22 | #define MSG_MENU_BACK "\rНазад"
23 | #define MSG_MENU_EXIT "\rВыход"
24 |
25 | #define MSG_VOTE_START "^1[^4%s^1] ^3%n^4 Запустил голосование за ^1gag ^4игрока ^3%n^1!"
26 | #define MSG_VOTE_EXISTS "^1[^4%s^1] ^4Голосование за ^1gag ^4игрока ^3уже запужено!"
27 | #define MSG_VOTE_BLOCK "^1[^4%s^1] ^4Голосование будет доступно через ^3%d сек."
28 | #define MSG_VOTING_FAIL "^1[^4%s^1] ^4Голосование завершилось ^3неудачно^4. Недостаточно голосов ^1[^3%d^1/^3%d^1]"
29 | #define MSG_VOTING_OK_ALL "^1[^4%s^1] ^4Голосование завершилось ^3удачно^4. Игрок ^3%s ^4GAG'нут на ^3%d ^4мин."
30 | #define MSG_VOTING_OK_PL "^1[^4%s^1] ^4Голосование за Ваш GAG завершилось ^3удачно^4. Вам отключены чаты на ^3%d ^4мин."
31 | #define MSG_VOTING_DISC "^1[^4%s^1] ^4Игрок, за которого Вы запускали GAG голосование, покинул сервер"
32 | /* ======== EndLANG ======== */
33 |
34 |
35 | #if !defined MAX_PLAYERS
36 | const MAX_PLAYERS = 32
37 | #endif
38 |
39 | new g_VotingMenu
40 | new g_iVotingIndex, g_iVotingLasttime
41 | new g_arrPlayers[MAX_PLAYERS], g_iPnum
42 | new bool:g_bPlayerVoted[MAX_PLAYERS + 1], g_iPlayersVotedCount
43 |
44 |
45 | public plugin_init()
46 | {
47 | register_plugin("CA: VoteGAG", "1.0.1-alpha", "Sergey Shorokhov")
48 |
49 | register_clcmd("say /votegag", "clcmd_VoteGag")
50 | register_clcmd("say_team /votegag", "clcmd_VoteGag")
51 | register_clcmd("votegag", "clcmd_VoteGag")
52 | }
53 |
54 | public plugin_cfg()
55 | {
56 | g_VotingMenu = menu_create("Title", "voting_handler")
57 | menu_setprop(g_VotingMenu, MPROP_EXIT, MEXIT_NEVER)
58 | menu_additem(g_VotingMenu, MSG_MENU_YES, "1")
59 | menu_additem(g_VotingMenu, MSG_MENU_NO, "0")
60 | }
61 |
62 | public client_disconnected(id)
63 | {
64 | if (g_bPlayerVoted[id])
65 | {
66 | g_bPlayerVoted[id] = false
67 | g_iPlayersVotedCount--
68 | }
69 | }
70 |
71 | public clcmd_VoteGag(id)
72 | {
73 | if (g_iVotingIndex)
74 | {
75 | ChatColor(id, 0, MSG_VOTE_EXISTS, PREFIX)
76 | return PLUGIN_HANDLED
77 | }
78 | new time = g_iVotingLasttime + REPEAT_VOTE_MIN * 60 - get_systime()
79 | if (time > 0)
80 | {
81 | ChatColor(id, 0, MSG_VOTE_BLOCK, PREFIX, time % 60)
82 | return PLUGIN_HANDLED
83 | }
84 |
85 | new szName[32], num[3], menu, callback
86 | menu = menu_create(MSG_PLMENU_TITLE, "players_handler")
87 | callback = menu_makecallback("players_callback")
88 |
89 | menu_setprop(menu, MPROP_NEXTNAME, MSG_MENU_NEXT)
90 | menu_setprop(menu, MPROP_BACKNAME, MSG_MENU_BACK)
91 | menu_setprop(menu, MPROP_EXITNAME, MSG_MENU_EXIT)
92 |
93 | get_players(g_arrPlayers, g_iPnum, "h")
94 |
95 | for(new i; i < g_iPnum; i++)
96 | {
97 | if (g_arrPlayers[i] == id)
98 | continue
99 |
100 | get_user_name(g_arrPlayers[i], szName, charsmax(szName))
101 | num_to_str(g_arrPlayers[i], num, charsmax(num))
102 | menu_additem(menu, szName, num, .callback = callback)
103 | }
104 |
105 | menu_display(id, menu)
106 | return PLUGIN_HANDLED
107 | }
108 |
109 | public players_callback(id, menu, item)
110 | {
111 | new _access, item_data[3], callback
112 | menu_item_getinfo(menu, item, _access, item_data, charsmax(item_data), .callback = callback)
113 |
114 | new index = str_to_num(item_data)
115 | if (!is_user_connected(index))
116 | return ITEM_DISABLED
117 | if (ca_has_user_gag(index))
118 | return ITEM_DISABLED
119 | if (get_user_flags(index) & IMMUNITY_FLAGS)
120 | return ITEM_DISABLED
121 |
122 | return ITEM_ENABLED
123 | }
124 |
125 | public players_handler(id, menu, item)
126 | {
127 | if (item == MENU_EXIT)
128 | {
129 | menu_destroy(menu)
130 | return PLUGIN_HANDLED
131 | }
132 |
133 | new _access, item_data[3], callback
134 | menu_item_getinfo(menu, item, _access, item_data, charsmax(item_data), .callback = callback)
135 | g_iVotingIndex = str_to_num(item_data)
136 | menu_destroy(menu)
137 |
138 | new szTitle[128], szName[32]
139 | get_user_name(g_iVotingIndex, szName, charsmax(szName))
140 |
141 | formatex(szTitle, charsmax(szTitle), MSG_VMENU_TITLE, szName)
142 | menu_setprop(g_VotingMenu, MPROP_TITLE, szTitle)
143 |
144 | ChatColor(0, g_iVotingIndex, MSG_VOTE_START, PREFIX, id, g_iVotingIndex)
145 |
146 | for(new i; i < g_iPnum; i++)
147 | {
148 | if (g_arrPlayers[i] == g_iVotingIndex)
149 | continue
150 |
151 | if (is_user_connected(g_arrPlayers[i]))
152 | menu_display(g_arrPlayers[i], g_VotingMenu)
153 | }
154 |
155 | set_task(CHECK_VOTE_TIME, "task__CheckVotes", id)
156 | return PLUGIN_HANDLED
157 | }
158 |
159 | public voting_handler(id, menu, item)
160 | {
161 | if (item == MENU_EXIT)
162 | return PLUGIN_HANDLED
163 |
164 | new _access, item_data[3], callback
165 | menu_item_getinfo(menu, item, _access, item_data, charsmax(item_data), .callback = callback)
166 |
167 | if (str_to_num(item_data))
168 | {
169 | g_iPlayersVotedCount++
170 | g_bPlayerVoted[id] = true
171 | }
172 | return PLUGIN_HANDLED
173 | }
174 |
175 | public task__CheckVotes(id)
176 | {
177 | for(new i; i < g_iPnum; i++)
178 | {
179 | if (is_user_connected(g_arrPlayers[i]))
180 | show_menu(g_arrPlayers[i], 0, "^n")
181 | }
182 |
183 | new iVoteCount = floatround(g_iPnum * PERCENT_VOTE_OK / 100.0)
184 |
185 | if (g_iPlayersVotedCount >= iVoteCount)
186 | {
187 | if (is_user_connected(g_iVotingIndex))
188 | {
189 | ca_set_user_gag(g_iVotingIndex, PREFIX, BLOCK_TIME_MIN, (gagFlag_Say | gagFlag_SayTeam | gagFlag_Voice))
190 |
191 | new szName[32]
192 | get_user_name(g_iVotingIndex, szName, charsmax(szName))
193 | ChatColor(0, g_iVotingIndex, MSG_VOTING_OK_ALL, PREFIX, szName, BLOCK_TIME_MIN)
194 | ChatColor(g_iVotingIndex, 0, MSG_VOTING_OK_PL, PREFIX, BLOCK_TIME_MIN)
195 | }
196 | else ChatColor(id, 0, MSG_VOTING_DISC, PREFIX)
197 | }
198 | else ChatColor(0, g_iVotingIndex, MSG_VOTING_FAIL, PREFIX, g_iPlayersVotedCount, iVoteCount)
199 |
200 | arrayset(g_bPlayerVoted, false, sizeof g_bPlayerVoted)
201 | g_iPlayersVotedCount = 0
202 | g_iVotingIndex = 0
203 | g_iVotingLasttime = get_systime()
204 | }
205 |
206 | stock ChatColor(id, id2, const szMessage[], any:...)
207 | {
208 | new szMsg[190]
209 | vformat(szMsg, charsmax(szMsg), szMessage, 4)
210 |
211 | if (id)
212 | {
213 | client_print_color(id, print_team_default, szMsg)
214 | }
215 | else
216 | {
217 | new players[32], pnum
218 | get_players(players, pnum, "c")
219 | for(new i; i < pnum; ++i)
220 | {
221 | if (players[i] != id2)
222 | {
223 | client_print_color(players[i], print_team_default, szMsg)
224 | }
225 | }
226 | }
227 | }
228 |
--------------------------------------------------------------------------------
/cstrike/addons/amxmodx/scripting/ChatAdditions/CA_AntiFlood.sma:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #pragma tabsize 4
5 |
6 | new g_OldMessage[MAX_PLAYERS + 1][CA_MAX_MESSAGE_SIZE]
7 |
8 | new Float: ca_anti_flood_time,
9 | ca_equal_messages
10 |
11 | public stock const PluginName[] = "CA: Anti Flood"
12 | public stock const PluginVersion[] = CA_VERSION
13 | public stock const PluginAuthor[] = "Nordic Warrior"
14 | public stock const PluginURL[] = "https://github.com/ChatAdditions/"
15 | public stock const PluginDescription[] = "Antiflood for text chat"
16 |
17 | public plugin_init() {
18 | register_plugin(PluginName, PluginVersion, PluginAuthor)
19 |
20 | register_dictionary("CA_AntiFlood.txt")
21 |
22 | Create_CVars()
23 |
24 | AutoExecConfig(true, "CA_AntiFlood", "ChatAdditions")
25 | }
26 |
27 | public plugin_cfg() {
28 | if (find_plugin_byfile("antiflood.amxx") != INVALID_PLUGIN_ID) {
29 | log_amx("Default plugin was found. It has been stopped.")
30 | pause("acd", "antiflood.amxx")
31 | }
32 | }
33 |
34 | public CA_Client_Say(id, const bool: isTeamMessage, const message[]) {
35 | return CheckMessage(id, message)
36 | }
37 |
38 |
39 | CheckMessage(id, const message[]) {
40 | if (message[0] == '/') {
41 | return CA_CONTINUE
42 | }
43 |
44 | static Float:nextMessage[MAX_PLAYERS + 1]
45 | static equalMessage[MAX_PLAYERS + 1]
46 |
47 | new Float:nextSay = get_gametime()
48 |
49 | if (nextMessage[id] > nextSay) {
50 | client_print_color(id, print_team_red, "%L %L", id, "CA_ANTIFLOOD_CHAT_PREFIX", id, "CA_ANTIFLOOD_CHAT_STOP_FLOODING")
51 | nextMessage[id] = nextSay + ca_anti_flood_time
52 |
53 | return CA_SUPERCEDE
54 | }
55 |
56 | if (strcmp(message, g_OldMessage[id], true) == 0) {
57 | if (++equalMessage[id] >= ca_equal_messages) {
58 | client_print_color(id, print_team_red, "%L %L", id, "CA_ANTIFLOOD_CHAT_PREFIX", id, "CA_ANTIFLOOD_CHAT_EQUAL_MESSAGE")
59 |
60 | return CA_SUPERCEDE
61 | }
62 | } else {
63 | equalMessage[id] = 0
64 | }
65 |
66 | nextMessage[id] = nextSay + ca_anti_flood_time
67 | copy(g_OldMessage[id], charsmax(g_OldMessage[]), message)
68 |
69 | return CA_CONTINUE
70 | }
71 |
72 | public client_disconnected(id) {
73 | g_OldMessage[id][0] = EOS
74 | }
75 |
76 | Create_CVars() {
77 | bind_pcvar_float(
78 | create_cvar(
79 | .name = "ca_anti_flood_time",
80 | .string = "0.75",
81 | .description = "Time between messages^n 0.0 - no limit",
82 | .has_min = true,
83 | .min_val = 0.0
84 | ),
85 |
86 | ca_anti_flood_time
87 | )
88 |
89 | bind_pcvar_num(
90 | create_cvar(
91 | .name = "ca_equal_messages",
92 | .string = "2",
93 | .description = "How many identical messages can be written in a row^n 0 - no limit",
94 | .has_min = true,
95 | .min_val = 0.0
96 | ),
97 |
98 | ca_equal_messages
99 | )
100 | }
101 |
--------------------------------------------------------------------------------
/cstrike/addons/amxmodx/scripting/ChatAdditions/CA_Mute.sma:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | #include
6 |
7 | #pragma tabsize 4
8 |
9 | #pragma reqlib sqlite
10 | #if !defined AMXMODX_NOAUTOLOAD
11 | #pragma loadlib sqlite
12 | #endif
13 |
14 | new bool: g_playersMute[MAX_PLAYERS + 1][MAX_PLAYERS + 1]
15 | new bool: g_globalMute[MAX_PLAYERS + 1]
16 |
17 | new Float: g_nextUse[MAX_PLAYERS + 1]
18 |
19 | new Float: ca_mute_use_delay,
20 | bool: ca_mute_use_storage
21 |
22 | new g_dummy, g_itemInfo[64], g_itemName[128]
23 |
24 | enum {
25 | ITEM_NOT_ENOUTH_PLAYERS = -2,
26 | ITEM_MUTE_ALL = -1
27 | }
28 |
29 | const QUERY_LENGTH = 4096
30 | new const g_mute_table[] = "ca_players_mute"
31 | new Handle: g_tuple = Empty_Handle
32 |
33 | public stock const PluginName[] = "CA: Mute"
34 | public stock const PluginVersion[] = CA_VERSION
35 | public stock const PluginAuthor[] = "Sergey Shorokhov"
36 | public stock const PluginURL[] = "https://github.com/ChatAdditions/"
37 | public stock const PluginDescription[] = "Players can choose who they can hear."
38 |
39 | public plugin_init() {
40 | register_plugin(PluginName, PluginVersion, PluginAuthor)
41 |
42 | register_dictionary("CA_Mute.txt")
43 | register_dictionary("common.txt")
44 |
45 | Create_CVars()
46 |
47 | new const CMDS_Mute[][] = { "mute" }
48 |
49 | for(new i; i < sizeof(CMDS_Mute); i++) {
50 | register_trigger_clcmd(CMDS_Mute[i], "ClCmd_Mute", ADMIN_ALL, .FlagManager = false)
51 | }
52 |
53 | AutoExecConfig(true, "CA_Mute", "ChatAdditions")
54 |
55 | Storage_Init()
56 |
57 | CA_Log(logLevel_Debug, "[CA]: Mute initialized!")
58 | }
59 |
60 | public plugin_end() {
61 | if (g_tuple != Empty_Handle)
62 | SQL_FreeHandle(g_tuple)
63 | }
64 |
65 | Create_CVars() {
66 | bind_pcvar_float(create_cvar("ca_mute_use_delay", "3",
67 | .description = "How often players can use menu. (in seconds)",
68 | .has_min = true, .min_val = 0.0,
69 | .has_max = true, .max_val = 120.0
70 | ),
71 | ca_mute_use_delay
72 | )
73 |
74 | bind_pcvar_num(create_cvar("ca_mute_use_storage", "1",
75 | .description = "Save the player's individual preferences in the vault.",
76 | .has_min = true, .min_val = 0.0,
77 | .has_max = true, .max_val = 1.0
78 | ),
79 | ca_mute_use_storage
80 | )
81 | }
82 |
83 | public ClCmd_Mute(const id) {
84 | if (!is_user_connected(id)) {
85 | return PLUGIN_CONTINUE
86 | }
87 |
88 | if (get_playersnum_ex(GetPlayers_ExcludeBots | GetPlayers_ExcludeHLTV) < 2) {
89 | client_print_color(id, print_team_default, "%L %L", id, "Mute_prefix", id, "Mute_NotEnoughPlayers")
90 | return PLUGIN_HANDLED
91 | }
92 |
93 | MenuShow_PlayersList(id)
94 |
95 | return PLUGIN_HANDLED
96 | }
97 |
98 | static MenuShow_PlayersList(const id) {
99 | if (!is_user_connected(id)) {
100 | return
101 | }
102 |
103 | new menu = menu_create(fmt("%L", id, "Mute_MenuTitle"), "MenuHandler_PlayersList")
104 |
105 | static callback
106 |
107 | if (!callback) {
108 | callback = menu_makecallback("MenuCallback_PlayersList")
109 | }
110 |
111 | new players[MAX_PLAYERS], count
112 | get_players_ex(players, count, .flags = (GetPlayers_ExcludeBots | GetPlayers_ExcludeHLTV))
113 |
114 | if (count < 2) {
115 | menu_additem(menu, fmt("\r %L", id, "Mute_NotEnoughPlayers"), fmt("%i", ITEM_NOT_ENOUTH_PLAYERS), .callback = callback)
116 | } else {
117 | menu_additem(menu, fmt("\y %L %s^n", id, "Mute_MuteAll", g_globalMute[id] ? "\w[ \r+\w ]" : ""), fmt("%i", ITEM_MUTE_ALL))
118 |
119 | new name[128]
120 | for(new i; i < count; i++) {
121 | new target = players[i]
122 |
123 | if (target == id) {
124 | continue
125 | }
126 |
127 | get_user_name(target, name, charsmax(name))
128 |
129 | if (g_playersMute[id][target] || CA_PlayerHasBlockedPlayer(id, target)) {
130 | strcat(name, " \d[ \r+\d ]", charsmax(name))
131 | }
132 |
133 | if (g_globalMute[target] || g_playersMute[target][id] || CA_PlayerHasBlockedPlayer(target, id)) {
134 | strcat(name, fmt(" \d(\y%L\d)", id, "Mute_PlayerMutedYou"), charsmax(name))
135 | }
136 |
137 | menu_additem(menu, name, fmt("%i", get_user_userid(target)), .callback = callback)
138 | }
139 | }
140 |
141 | menu_setprop(menu, MPROP_BACKNAME, fmt("%L", id, "BACK"))
142 | menu_setprop(menu, MPROP_NEXTNAME, fmt("%L", id, "MORE"))
143 | menu_setprop(menu, MPROP_EXITNAME, fmt("%L", id, "EXIT"))
144 |
145 | menu_display(id, menu)
146 | }
147 |
148 | public MenuCallback_PlayersList(const id, const menu, const item) {
149 | menu_item_getinfo(menu, item, g_dummy, g_itemInfo, charsmax(g_itemInfo), g_itemName, charsmax(g_itemName), g_dummy)
150 |
151 | new userID = strtol(g_itemInfo)
152 |
153 | if (userID == ITEM_NOT_ENOUTH_PLAYERS) {
154 | return ITEM_DISABLED
155 | }
156 |
157 | // Disable all players in menu when local user muted all
158 | if (userID != ITEM_MUTE_ALL && g_globalMute[id]) {
159 | return ITEM_DISABLED
160 | }
161 |
162 | new target = find_player_ex((FindPlayer_MatchUserId | FindPlayer_ExcludeBots), userID)
163 |
164 | if (CA_PlayerHasBlockedPlayer(id, target)) {
165 | return ITEM_DISABLED
166 | }
167 |
168 | return ITEM_ENABLED
169 | }
170 |
171 | public MenuHandler_PlayersList(const id, const menu, const item) {
172 | if (item == MENU_EXIT || item < 0) {
173 | menu_destroy(menu)
174 | return PLUGIN_HANDLED
175 | }
176 |
177 | menu_item_getinfo(menu, item, g_dummy, g_itemInfo, charsmax(g_itemInfo), g_itemName, charsmax(g_itemName), g_dummy)
178 | menu_destroy(menu)
179 |
180 | new Float: gametime = get_gametime()
181 |
182 | if (g_nextUse[id] > gametime) {
183 | client_print_color(id, print_team_red, "%L %L", id, "Mute_prefix", id, "Mute_UseTooOften")
184 | MenuShow_PlayersList(id)
185 | return PLUGIN_HANDLED
186 | }
187 |
188 | g_nextUse[id] = gametime + ca_mute_use_delay
189 |
190 | new userID = strtol(g_itemInfo)
191 |
192 | if (userID == ITEM_MUTE_ALL) {
193 | g_globalMute[id] ^= true
194 | Storage_Update(id, ITEM_MUTE_ALL)
195 |
196 | client_print_color(0, print_team_default, "%L ^3%n^1 %L ", id, "Mute_prefix",
197 | id, LANG_PLAYER, g_globalMute[id] ? "Mute_PlayerNowMutedAll" : "Mute_PlayerNowUnmutedAll"
198 | )
199 |
200 | CA_Log(logLevel_Info, "Mute: ^"%N^" %sMuted everyone", id, g_globalMute[id] ? "" : "Un")
201 | MenuShow_PlayersList(id)
202 | return PLUGIN_HANDLED
203 | }
204 |
205 | new player = find_player_ex((FindPlayer_MatchUserId | FindPlayer_ExcludeBots), userID)
206 |
207 | if (player == 0) {
208 | client_print_color(id, print_team_red, "%L %L", id, "Mute_prefix", id, "Mute_PlayerNotConnected")
209 | MenuShow_PlayersList(id)
210 | return PLUGIN_HANDLED
211 | }
212 |
213 | g_playersMute[id][player] ^= true
214 | Storage_Update(id, player)
215 |
216 | client_print_color(id, print_team_default, "%L %L ^3%n^1", id, "Mute_prefix",
217 | id, g_playersMute[id][player] ? "Mute_YouMutePlayer" : "Mute_YouUnmutePlayer", player
218 | )
219 |
220 | client_print_color(player, print_team_default, "%L ^3%n^1 %L ", id, "Mute_prefix",
221 | id, player, g_playersMute[id][player] ? "Mute_PlayerNowMutedYou" : "Mute_PlayerNowUnmutedYou"
222 | )
223 |
224 | CA_Log(logLevel_Info, "Mute: '%N' %smuted '%N'", id, g_playersMute[id][player] ? "" : "Un", player)
225 | MenuShow_PlayersList(id)
226 | return PLUGIN_HANDLED
227 | }
228 |
229 |
230 | public client_disconnected(id) {
231 | arrayset(g_playersMute[id], false, sizeof(g_playersMute[]))
232 | g_globalMute[id] = false
233 | g_nextUse[id] = 0.0
234 |
235 | for(new i; i < sizeof(g_playersMute[]); i++) {
236 | if (!g_playersMute[i][id])
237 | continue
238 |
239 | g_playersMute[i][id] = false
240 | }
241 | }
242 |
243 | public CA_Client_Voice(const listener, const sender) {
244 | if (g_globalMute[listener]) {
245 | return CA_SUPERCEDE
246 | }
247 |
248 | if (g_globalMute[sender]) {
249 | return CA_SUPERCEDE
250 | }
251 |
252 | if (g_playersMute[listener][sender] == true) {
253 | return CA_SUPERCEDE
254 | }
255 |
256 | return CA_CONTINUE
257 | }
258 |
259 | Storage_Init() {
260 | if (!SQL_SetAffinity("sqlite")) {
261 | set_fail_state("Can't user 'SQLite'. Check modules.ini")
262 | }
263 |
264 | g_tuple = SQL_MakeDbTuple("", "", "", g_mute_table)
265 |
266 | Storage_Create()
267 | }
268 |
269 | Storage_Create() {
270 | new query[QUERY_LENGTH / 2]
271 |
272 | formatex(query, charsmax(query), "CREATE TABLE IF NOT EXISTS %s", g_mute_table); {
273 | strcat(query, " ( id INTEGER PRIMARY KEY AUTOINCREMENT,", charsmax(query))
274 | strcat(query, "authid VARCHAR NOT NULL,", charsmax(query))
275 | strcat(query, "authid_target VARCHAR NOT NULL); ", charsmax(query))
276 | strcat(query, fmt("CREATE UNIQUE INDEX IF NOT EXISTS authid_target_idx1 ON %s (authid, authid_target)", g_mute_table), charsmax(query))
277 | }
278 |
279 | SQL_ThreadQuery(g_tuple, "handle_StorageCreated", query)
280 | }
281 |
282 | public handle_StorageCreated(failstate, Handle: query, error[], errnum, data[], size, Float: queuetime) {
283 | if (IsSQLQueryFailed(failstate, query, error, errnum)) {
284 | return
285 | }
286 |
287 | CA_Log(logLevel_Debug, "Table '%s' created! (queryTime: '%.3f' sec)", g_mute_table, queuetime)
288 | }
289 |
290 | public client_putinserver(player) {
291 | Storage_Load(player)
292 | }
293 |
294 | Storage_Update(const player, const target) {
295 | if (!ca_mute_use_storage)
296 | return
297 |
298 | new query[QUERY_LENGTH / 2]
299 |
300 | new authId[MAX_AUTHID_LENGTH]
301 | get_user_authid(player, authId, charsmax(authId))
302 |
303 | if (target == ITEM_MUTE_ALL) {
304 | if (g_globalMute[player]) {
305 | formatex(query, charsmax(query), "INSERT INTO %s (authid, authid_target)", g_mute_table)
306 | strcat(query, fmt(" VALUES ('%s', '%s') ON CONFLICT DO NOTHING", authId, "GLOBAL"), charsmax(query))
307 | } else {
308 | formatex(query, charsmax(query), "DELETE FROM %s", g_mute_table)
309 | strcat(query, fmt(" WHERE authid='%s' AND authid_target = '%s'", authId, "GLOBAL"), charsmax(query))
310 | }
311 |
312 | SQL_ThreadQuery(g_tuple, "handle_Saved", query)
313 | return
314 | }
315 |
316 | new authId_target[MAX_AUTHID_LENGTH]
317 | get_user_authid(target, authId_target, charsmax(authId_target))
318 |
319 | if (g_playersMute[player][target]) {
320 | formatex(query, charsmax(query), "INSERT INTO %s (authid, authid_target)", g_mute_table)
321 | strcat(query, fmt(" VALUES ('%s', '%s') ON CONFLICT DO NOTHING", authId, authId_target), charsmax(query))
322 | } else {
323 | formatex(query, charsmax(query), "DELETE FROM %s", g_mute_table)
324 | strcat(query, fmt(" WHERE authid ='%s' AND authid_target = '%s'", authId, authId_target), charsmax(query))
325 | }
326 |
327 | SQL_ThreadQuery(g_tuple, "handle_Saved", query)
328 | }
329 |
330 | public handle_Saved(failstate, Handle: query, error[], errnum, data[], size, Float: queuetime) {
331 | if (IsSQLQueryFailed(failstate, query, error, errnum)) {
332 | return
333 | }
334 | }
335 |
336 | Storage_Load(const player) {
337 | if (!ca_mute_use_storage)
338 | return
339 |
340 | new authId[MAX_AUTHID_LENGTH]
341 | get_user_authid(player, authId, charsmax(authId))
342 |
343 | new query[QUERY_LENGTH / 2]
344 | formatex(query, charsmax(query), "SELECT authid, authid_target FROM %s", g_mute_table)
345 | strcat(query, fmt(" WHERE authid ='%s' OR authid_target = '%s'", authId, authId), charsmax(query))
346 |
347 | SQL_ThreadQuery(g_tuple, "handle_LoadedMute", query)
348 | }
349 |
350 | public handle_LoadedMute(failstate, Handle: query, error[], errnum, data[], size, Float: queuetime) {
351 | if (IsSQLQueryFailed(failstate, query, error, errnum)) {
352 | return
353 | }
354 |
355 | if (!SQL_NumResults(query))
356 | return
357 |
358 | while (SQL_MoreResults(query)) {
359 | new authId[MAX_AUTHID_LENGTH], authId_target[MAX_AUTHID_LENGTH]
360 | SQL_ReadResult(query, 0, authId, charsmax(authId))
361 | SQL_ReadResult(query, 1, authId_target, charsmax(authId_target))
362 |
363 | new player = find_player_ex(FindPlayer_MatchAuthId, authId)
364 | if (player == 0) {
365 | goto next
366 | }
367 |
368 | if (strcmp(authId_target, "GLOBAL") == 0) {
369 | g_globalMute[player] = true
370 | goto next
371 | }
372 |
373 | new target = find_player_ex(FindPlayer_MatchAuthId, authId_target)
374 | if (target == 0) {
375 | goto next
376 | }
377 |
378 | g_playersMute[player][target] = true
379 |
380 | next:
381 | SQL_NextRow(query)
382 | }
383 | }
384 |
385 | static stock bool: IsSQLQueryFailed(const failstate, const Handle: query, const error[], const errNum) {
386 | switch (failstate) {
387 | case TQUERY_CONNECT_FAILED: {
388 | log_amx("SQL: connection failed [%i] `%s`", errNum, error)
389 | return true
390 | }
391 | case TQUERY_QUERY_FAILED: {
392 | log_amx("SQL: query failed [%i] %s", errNum, error)
393 |
394 | server_print("^n^n ===> Query:")
395 | new buffer[1024]; SQL_GetQueryString(query, buffer, charsmax(buffer))
396 | for(new i, len = strlen(buffer); i < len; i+=255) {
397 | server_print(fmt("%-255s", buffer[i]))
398 | }
399 |
400 | return true
401 | }
402 | }
403 |
404 | return false
405 | }
406 |
--------------------------------------------------------------------------------
/cstrike/addons/amxmodx/scripting/ChatAdditions/ChatAdditions_Core.sma:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | #include
6 | #include
7 |
8 | #pragma tabsize 4
9 | #pragma dynamic (8192 + 4096)
10 |
11 |
12 | enum logType_s {
13 | _Default,
14 | _LogToDir,
15 | _LogToDirSilent,
16 | _LogToAlertMessage,
17 | }
18 |
19 | new logType_s: ca_log_type,
20 | logLevel_s: ca_log_level = logLevel_Debug,
21 | bool: ca_update_notify,
22 | ca_log_autodelete_time
23 |
24 | new const LOG_FOLDER[] = "ChatAdditions"
25 |
26 | new g_fwdClientSay,
27 | g_fwdClientVoice,
28 | g_fwdClientChangeName,
29 | g_retVal
30 |
31 | // FROM https://github.com/s1lentq/ReGameDLL_CS/blob/master/regamedll/game_shared/voice_gamemgr.cpp
32 |
33 | // Set to 1 for each player if the player wants to use voice in this mod.
34 | // (If it's zero, then the server reports that the game rules are saying the player can't hear anyone).
35 | new bool: g_PlayerModEnable[MAX_PLAYERS + 1]
36 |
37 | // Tells which players don't want to hear each other.
38 | // These are indexed as clients and each bit represents a client (so player entity is bit + 1).
39 | new g_BanMasks[MAX_PLAYERS + 1]
40 |
41 | new const g_versionLink[] = "https://api.github.com/repos/"
42 | + "ChatAdditions/ChatAdditions_AMXX"
43 | + "/releases/latest"
44 |
45 | public stock const PluginName[] = "ChatAdditions: Core"
46 | public stock const PluginVersion[] = CA_VERSION
47 | public stock const PluginAuthor[] = "Sergey Shorokhov"
48 | public stock const PluginURL[] = "https://github.com/ChatAdditions/"
49 | public stock const PluginDescription[] = "A core plugin for control different types of chat."
50 |
51 | public plugin_precache() {
52 | register_plugin(PluginName, PluginVersion, PluginAuthor)
53 |
54 | create_cvar("ChatAdditions_version", PluginVersion, FCVAR_SERVER)
55 |
56 | Create_CVars()
57 | CheckUpdate()
58 | }
59 |
60 | public plugin_init() {
61 | register_clcmd("say", "ClCmd_Say", ADMIN_ALL)
62 | register_clcmd("say_team", "ClCmd_Say", ADMIN_ALL)
63 |
64 | register_forward(FM_Voice_SetClientListening, "Voice_SetClientListening_Pre", ._post = false)
65 | register_forward(FM_ClientUserInfoChanged, "ClientUserInfoChanged_Pre", ._post = false)
66 |
67 | register_clcmd("VModEnable", "ClCmd_VModEnable", ADMIN_ALL, .FlagManager = false)
68 | register_clcmd("vban", "ClCmd_vban", ADMIN_ALL, .FlagManager = false)
69 |
70 | g_fwdClientSay = CreateMultiForward("CA_Client_Say", ET_STOP, FP_CELL, FP_CELL, FP_STRING)
71 | g_fwdClientVoice = CreateMultiForward("CA_Client_Voice", ET_STOP, FP_CELL, FP_CELL)
72 | g_fwdClientChangeName = CreateMultiForward("CA_Client_ChangeName", ET_STOP, FP_CELL, FP_STRING)
73 |
74 | CheckAutoDelete()
75 |
76 | CA_Log(logLevel_Debug, "Chat Additions: Core initialized!")
77 | }
78 |
79 | public plugin_end() {
80 | DestroyForward(g_fwdClientSay)
81 | DestroyForward(g_fwdClientVoice)
82 | DestroyForward(g_fwdClientChangeName)
83 | }
84 |
85 | CheckAutoDelete() {
86 | if (ca_log_autodelete_time <= 0)
87 | return
88 |
89 | new logsPath[PLATFORM_MAX_PATH]
90 | GetLogsFilePath(logsPath, .dir = LOG_FOLDER)
91 |
92 | if (!dir_exists(logsPath))
93 | return
94 |
95 | new logFile[PLATFORM_MAX_PATH]
96 | new dirHandle
97 | dirHandle = open_dir(logsPath, logFile, charsmax(logFile))
98 | if (!dirHandle)
99 | return
100 |
101 | new subDirectory[PLATFORM_MAX_PATH]
102 | new deleteTime = get_systime() - (ca_log_autodelete_time * (60 * 60 * 24))
103 |
104 | while (next_file(dirHandle, logFile, charsmax(logFile))) {
105 | if (logFile[0] == '.')
106 | continue
107 |
108 | if (containi(logFile, ".log") == -1) {
109 | formatex(subDirectory, charsmax(subDirectory), "%s/%s", logsPath, logFile)
110 |
111 | // TODO: refactor this
112 | ReadFolder(deleteTime, subDirectory)
113 |
114 | continue
115 | }
116 | }
117 |
118 | close_dir(dirHandle)
119 | }
120 |
121 | ReadFolder(deleteTime, logPath[]) {
122 | new logFile[PLATFORM_MAX_PATH]
123 | new dirHandle = open_dir(logPath, logFile, charsmax(logFile))
124 | new fileTime
125 |
126 | if (dirHandle) {
127 | do
128 | {
129 | if (logFile[0] == '.') {
130 | continue
131 | }
132 |
133 | if (containi(logFile, ".log") != -1) {
134 | fileTime = 0
135 | format(logFile, charsmax(logFile), "%s/%s", logPath, logFile)
136 |
137 | fileTime = GetFileTime(logFile, FileTime_Created)
138 | if (fileTime < deleteTime) {
139 | unlink(logFile)
140 | }
141 | }
142 | } while (next_file(dirHandle, logFile, charsmax(logFile)))
143 | }
144 | close_dir(dirHandle)
145 | }
146 |
147 | Create_CVars() {
148 |
149 | bind_pcvar_num(create_cvar("ca_log_type", "1",
150 | .description = fmt("Log file type^n \
151 | 0 = log to common amxx log file (logs/L*.log)^n \
152 | 1 = log to plugins folder (logs/%s/[plugin name]/L*.log)^n \
153 | 2 = silent log to plugins folder (logs/%s/[plugin name]/L*.log)^n \
154 | 3 = use elog_message) \
155 | ",
156 | LOG_FOLDER, LOG_FOLDER),
157 | .has_min = true, .min_val = 0.0,
158 | .has_max = true, .max_val = float(logType_s) - 1.0
159 | ),
160 | ca_log_type
161 | )
162 |
163 | bind_pcvar_num(create_cvar("ca_log_level", "1",
164 | .description = "Log level^n \
165 | 0 = disable logs^n \
166 | 1 = add info messages logs^n \
167 | 2 = add warinigs info^n \
168 | 3 = add debug messages",
169 | .has_min = true, .min_val = 0.0,
170 | .has_max = true, .max_val = float(logLevel_s) - 1.0
171 | ),
172 | ca_log_level
173 | )
174 |
175 | bind_pcvar_num(create_cvar("ca_update_notify", "1",
176 | .description = "Enable update check?^n 0 = disable update checks",
177 | .has_min = true, .min_val = 0.0,
178 | .has_max = true, .max_val = 1.0
179 | ),
180 | ca_update_notify
181 | )
182 |
183 | bind_pcvar_num(create_cvar("ca_log_autodelete_time", "7",
184 | .description = "The time in days after which the log files should be deleted.^n \
185 | 0 - The logs won't be deleted.^n \
186 | > 0 - The logs will be deleted at the time inserted.",
187 | .has_min = true, .min_val = 0.0
188 | ),
189 | ca_log_autodelete_time
190 | )
191 |
192 | AutoExecConfig(true, "ChatAdditions_core", LOG_FOLDER)
193 |
194 | new configsDir[PLATFORM_MAX_PATH]
195 | get_configsdir(configsDir, charsmax(configsDir))
196 |
197 | server_cmd("exec %s/plugins/%s/ChatAdditions_core.cfg", configsDir, LOG_FOLDER)
198 | server_exec()
199 | }
200 |
201 | public plugin_natives() {
202 | register_library("ChatAdditions_Core")
203 |
204 | set_module_filter("ModuleFilter")
205 | set_native_filter("NativeFilter")
206 |
207 | register_native("CA_Log", "native_CA_Log")
208 | register_native("CA_PlayerHasBlockedPlayer", "native_CA_PlayerHasBlockedPlayer")
209 | }
210 |
211 | public ModuleFilter(const library[], LibType: type) {
212 | return strcmp("easy_http", library) == 0 ? PLUGIN_HANDLED : PLUGIN_CONTINUE
213 | }
214 |
215 | public NativeFilter(const nativeName[], index, trap) {
216 | if (strncmp(nativeName, "ezhttp_", 7) == 0)
217 | return PLUGIN_HANDLED
218 |
219 | if (strncmp(nativeName, "ezjson_", 7) == 0)
220 | return PLUGIN_HANDLED
221 |
222 | return PLUGIN_CONTINUE
223 | }
224 |
225 | public ClCmd_Say(const id) {
226 | static message[CA_MAX_MESSAGE_SIZE]
227 | read_argv(0, message, charsmax(message))
228 | new isTeamMessage = (message[3] == '_')
229 | read_args(message, charsmax(message))
230 | remove_quotes(message)
231 |
232 | ExecuteForward(g_fwdClientSay, g_retVal, id, isTeamMessage, message)
233 |
234 | return (g_retVal == CA_SUPERCEDE) ? PLUGIN_HANDLED : PLUGIN_CONTINUE
235 | }
236 |
237 | public Voice_SetClientListening_Pre(const receiver, const sender, bool: canListen) {
238 | if (receiver == sender)
239 | return FMRES_IGNORED
240 |
241 | if (!g_PlayerModEnable[receiver])
242 | return FMRES_IGNORED
243 |
244 | if (!is_user_connected(receiver) || !is_user_connected(sender))
245 | return FMRES_IGNORED
246 |
247 | ExecuteForward(g_fwdClientVoice, g_retVal, receiver, sender)
248 | if (g_retVal != CA_SUPERCEDE)
249 | return FMRES_IGNORED
250 |
251 | // Block voice
252 | engfunc(EngFunc_SetClientListening, receiver, sender, (canListen = false))
253 | return FMRES_SUPERCEDE
254 | }
255 |
256 | public ClientUserInfoChanged_Pre(const player, const infobuffer) {
257 | new currentName[32]
258 | get_user_name(player, currentName, charsmax(currentName))
259 |
260 | new newName[32]
261 | engfunc(EngFunc_InfoKeyValue, infobuffer, "name", newName, charsmax(newName))
262 |
263 | if (strcmp(currentName, newName) == 0)
264 | return
265 |
266 | ExecuteForward(g_fwdClientChangeName, g_retVal, player, newName)
267 | if (g_retVal != CA_SUPERCEDE)
268 | return
269 |
270 | // Change back name
271 | engfunc(EngFunc_SetClientKeyValue, player, infobuffer, "name", currentName)
272 | }
273 |
274 | public ClCmd_VModEnable(const id) {
275 | if (read_argc() < 2) {
276 | return
277 | }
278 |
279 | new arg[32]; read_argv(1, arg, charsmax(arg))
280 | g_PlayerModEnable[id] = bool: (strtol(arg) != 0)
281 | }
282 |
283 | public ClCmd_vban(const id) {
284 | if (read_argc() < 2) {
285 | return
286 | }
287 |
288 | new arg[32]; read_argv(1, arg, charsmax(arg))
289 | g_BanMasks[id] = strtol(arg, .base = 16)
290 | }
291 |
292 | public bool: native_CA_Log(const plugin_id, const argc) {
293 | enum { arg_level = 1, arg_msg, arg_format }
294 |
295 | new logLevel_s: level = logLevel_s: get_param(arg_level)
296 |
297 | if (ca_log_level < level)
298 | return false
299 |
300 | new msg[2048]
301 | vdformat(msg, charsmax(msg), arg_msg, arg_format)
302 |
303 | new logsFile[PLATFORM_MAX_PATH]
304 |
305 | if (ca_log_type == _LogToDir || ca_log_type == _LogToDirSilent) {
306 | new logsPath[PLATFORM_MAX_PATH]
307 | get_localinfo("amxx_logs", logsPath, charsmax(logsPath))
308 |
309 | new pluginName[PLATFORM_MAX_PATH]
310 | get_plugin(plugin_id, pluginName, charsmax(pluginName))
311 |
312 | replace(pluginName, charsmax(pluginName), ".amxx", "")
313 |
314 | formatex(logsPath, charsmax(logsPath), "%s/%s", logsPath, pluginName)
315 |
316 | if (!dir_exists(logsPath))
317 | mkdir(logsPath)
318 |
319 | new year, month, day
320 | date(year, month, day)
321 |
322 | formatex(logsFile, charsmax(logsFile), "%s/%s__%i-%02i-%02i.log",
323 | logsPath,
324 | pluginName[sizeof(LOG_FOLDER)],
325 | year, month, day
326 | )
327 | }
328 |
329 | switch (ca_log_type) {
330 | case _Default: log_amx(msg)
331 | case _LogToDir: log_to_file(logsFile, msg)
332 | case _LogToDirSilent: log_to_file_ex(logsFile, msg)
333 | case _LogToAlertMessage: elog_message(msg)
334 | }
335 |
336 | return true
337 | }
338 |
339 | public bool: native_CA_PlayerHasBlockedPlayer(const plugin_id, const argc) {
340 | enum { arg_receiver = 1, arg_sender }
341 |
342 | new receiver = get_param(arg_receiver)
343 | new sender = get_param(arg_sender)
344 |
345 | if (CVoiceGameMgr__PlayerHasBlockedPlayer(receiver, sender)) {
346 | return true
347 | }
348 |
349 | return false
350 | }
351 |
352 | static GetLogsFilePath(buffer[], len = PLATFORM_MAX_PATH, const dir[] = "ChatAdditions") {
353 | get_localinfo("amxx_logs", buffer, len)
354 | strcat(buffer, fmt("/%s", dir), len)
355 |
356 | if (!dir_exists(buffer) && mkdir(buffer) == -1) {
357 | set_fail_state("[Core API] Can't create folder! (%s)", buffer)
358 | }
359 | }
360 |
361 | static bool: CVoiceGameMgr__PlayerHasBlockedPlayer(const receiver, const sender) {
362 | #define CanPlayerHearPlayer(%0,%1) ( ~g_BanMasks[%0] & ( 1 << (%1 - 1) ) )
363 |
364 | if (receiver <= 0 || receiver > MaxClients || sender <= 0 || sender > MaxClients) {
365 | return false
366 | }
367 |
368 | return bool: !CanPlayerHearPlayer(receiver, sender)
369 | }
370 |
371 | static CheckUpdate() {
372 | if (!ca_update_notify)
373 | return
374 |
375 | if (strcmp(CA_VERSION, "CA_VERSION") == 0 || contain(CA_VERSION, ".") == -1) // ignore custom builds
376 | return
377 |
378 | if (is_module_loaded("Amxx Easy Http") == -1) {
379 | CA_Log(logLevel_Warning, "The `AmxxEasyHttp` module is not loaded! The new version cannot be verified.")
380 | CA_Log(logLevel_Warning, "Please install AmxxEasyHttp: `https://github.com/Next21Team/AmxxEasyHttp` or disable update checks (`ca_update_notify `0`).")
381 |
382 | return
383 | }
384 |
385 | RequestNewVersion(g_versionLink)
386 | }
387 |
388 | static RequestNewVersion(const link[]) {
389 | ezhttp_get(link, "@RequestHandler")
390 | }
391 |
392 | @RequestHandler(EzHttpRequest: request_id) {
393 | if (ezhttp_get_error_code(request_id) != EZH_OK) {
394 | new error[64]
395 | ezhttp_get_error_message(request_id, error, charsmax(error))
396 | server_print("Response error: %s", error)
397 | return
398 | }
399 |
400 |
401 | new response[8192]
402 | ezhttp_get_data(request_id, response, charsmax(response))
403 |
404 | if (contain(response, "tag_name") == -1) {
405 | CA_Log(logLevel_Warning, " > Wrong response! (don't contain `tag_name`). res=`%s`", response)
406 | return
407 | }
408 |
409 | new EzJSON: json = ezjson_parse(response)
410 | if (json == EzInvalid_JSON) {
411 | CA_Log(logLevel_Warning, " > Can't parse response JSON!")
412 | goto END
413 | }
414 |
415 | new tag_name[32]
416 | ezjson_object_get_string(json, "tag_name", tag_name, charsmax(tag_name))
417 |
418 | if (CmpVersions(CA_VERSION, tag_name) >= 0)
419 | goto END
420 |
421 | new html_url[256]
422 | ezjson_object_get_string(json, "html_url", html_url, charsmax(html_url))
423 |
424 | NotifyUpdate(tag_name, html_url)
425 |
426 | END:
427 | ezjson_free(json)
428 | }
429 |
430 | static NotifyUpdate(const newVersion[], const URL[]) {
431 | CA_Log(logLevel_Info, "^n^t ChatAdditions (%s) has update! New version `%s`.^n\
432 | Download link: `%s`", CA_VERSION, newVersion, URL
433 | )
434 | }
435 |
436 | static stock CmpVersions(const a[], const b[]) {
437 | new segmentsA[32][32]
438 | new segmentsB[32][32]
439 |
440 | new countA = explode_string(
441 | a[!isdigit(a[0]) ? 1 : 0],
442 | ".",
443 | segmentsA, sizeof segmentsA, charsmax(segmentsA[])
444 | )
445 |
446 | new countB = explode_string(
447 | b[!isdigit(b[0]) ? 1 : 0],
448 | ".",
449 | segmentsB, sizeof segmentsB, charsmax(segmentsB[])
450 | )
451 |
452 | for(new i, l = min(countA, countB); i < l; i++) {
453 | new diff = strtol(segmentsA[i]) - strtol(segmentsB[i])
454 | if (diff)
455 | return diff
456 | }
457 |
458 | return countA - countB
459 | }
460 |
461 | stock log_to_file_ex(const filePath[], message[]) {
462 | new file
463 | new bool:firstTime = true
464 | new date[32]
465 |
466 | format_time(date, charsmax(date), "%m/%d/%Y - %H:%M:%S")
467 | static modName[15], amxVersion[15]
468 |
469 | if (!modName[0]) {
470 | get_modname(modName, charsmax(modName))
471 | }
472 |
473 | if (!amxVersion[0]) {
474 | get_amxx_verstring(amxVersion, charsmax(amxVersion))
475 | }
476 |
477 | if ((file = fopen(filePath, "r"))) {
478 | firstTime = false
479 | fclose(file)
480 | }
481 |
482 | if (!(file = fopen(filePath, "at"))) {
483 | log_error(AMX_ERR_GENERAL, "Can't open ^"%s^" file for writing.", filePath)
484 | return PLUGIN_CONTINUE
485 | }
486 |
487 | if (firstTime) {
488 | fprintf(file, "L %s: Log file started (file ^"%s^") (game ^"%s^") (amx ^"%s^")^n", date, filePath, modName, amxVersion)
489 | }
490 |
491 | fprintf(file, "L %s: %s^n", date, message)
492 |
493 | fclose(file)
494 |
495 | return PLUGIN_HANDLED
496 | }
497 |
--------------------------------------------------------------------------------
/cstrike/addons/amxmodx/scripting/ChatAdditions/Storage/CA_Storage_CSBans.sma:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | #include
6 |
7 | #include
8 | #include
9 | #include
10 |
11 | #pragma dynamic 131072
12 | #pragma tabsize 4
13 |
14 | #pragma reqlib mysql
15 | #if !defined AMXMODX_NOAUTOLOAD
16 | #pragma loadlib mysql
17 | #endif
18 |
19 | new const SQL_TBL_GAGS[] = "chatadditions_gags"
20 |
21 | const QUERY_LENGTH = 4096
22 | const MAX_REASON_LENGTH = 256
23 | new g_query[QUERY_LENGTH]
24 |
25 | new Handle: g_tuple = Empty_Handle
26 | new Queue: g_queueLoad = Invalid_Queue,
27 | Queue: g_queueSave = Invalid_Queue
28 |
29 | new ca_storage_host[64],
30 | ca_storage_user[128],
31 | ca_storage_pass[128],
32 | ca_storage_dbname[128]
33 |
34 | public stock const PluginName[] = "ChatAdditions: CSBans storage"
35 | public stock const PluginVersion[] = CA_VERSION
36 | public stock const PluginAuthor[] = "Sergey Shorokhov"
37 | public stock const PluginURL[] = "https://github.com/ChatAdditions/"
38 | public stock const PluginDescription[] = "CSBans (MySQL) storage provider for ChatAdditions"
39 |
40 | public plugin_init() {
41 | register_plugin(PluginName, PluginVersion, PluginAuthor)
42 |
43 | if (!SQL_SetAffinity("mysql")) {
44 | set_fail_state("Can't user 'MySQL'. Check modules.ini")
45 | }
46 |
47 | Create_CVars()
48 |
49 | AutoExecConfig(true, "CA_Storage_CSBans", "ChatAdditions")
50 |
51 | g_queueLoad = QueueCreate(MAX_AUTHID_LENGTH)
52 | g_queueSave = QueueCreate(gagData_s)
53 |
54 | set_task_ex(6.274, "_OnConfigsExecuted")
55 | }
56 |
57 | public _OnConfigsExecuted() {
58 | g_tuple = SQL_MakeDbTuple(ca_storage_host, ca_storage_user, ca_storage_pass, ca_storage_dbname)
59 |
60 | Storage_Create()
61 | }
62 |
63 | public plugin_end() {
64 | if (g_tuple != Empty_Handle) {
65 | SQL_FreeHandle(g_tuple)
66 | }
67 |
68 | QueueDestroy(g_queueLoad)
69 | QueueDestroy(g_queueSave)
70 | }
71 |
72 | public plugin_natives() {
73 | RegisterNatives()
74 | }
75 |
76 | public plugin_cfg() {
77 | RegisterForwards()
78 | }
79 |
80 | Create_CVars() {
81 | bind_pcvar_string(create_cvar("ca_storage_host", "127.0.0.1", FCVAR_PROTECTED,
82 | .description = "CSBans MySQL database host address"
83 | ),
84 | ca_storage_host, charsmax(ca_storage_host)
85 | )
86 |
87 | bind_pcvar_string(create_cvar("ca_storage_user", "root", FCVAR_PROTECTED,
88 | .description = "CSBans MySQL database user"
89 | ),
90 | ca_storage_user, charsmax(ca_storage_user)
91 | )
92 |
93 | bind_pcvar_string(create_cvar("ca_storage_pass", "", FCVAR_PROTECTED,
94 | .description = "CSBans MySQL database host password"
95 | ),
96 | ca_storage_pass, charsmax(ca_storage_pass)
97 | )
98 |
99 | bind_pcvar_string(create_cvar("ca_storage_dbname", "players_gags", FCVAR_PROTECTED,
100 | .description = "CSBans MySQL database name (not recommended to change)"
101 | ),
102 | ca_storage_dbname, charsmax(ca_storage_dbname)
103 | )
104 | }
105 |
106 | Storage_Create() {
107 | formatex(g_query, charsmax(g_query), "CREATE TABLE IF NOT EXISTS %s ", SQL_TBL_GAGS); {
108 | strcat(g_query, "( id INTEGER PRIMARY KEY AUTO_INCREMENT,", charsmax(g_query))
109 | strcat(g_query, "name VARCHAR(32) NOT NULL,", charsmax(g_query))
110 | strcat(g_query, "authid VARCHAR(64) NOT NULL,", charsmax(g_query))
111 | strcat(g_query, "ip VARCHAR(22) NOT NULL,", charsmax(g_query))
112 | strcat(g_query, "reason VARCHAR(256) NOT NULL,", charsmax(g_query))
113 | strcat(g_query, "admin_name VARCHAR(32) NOT NULL,", charsmax(g_query))
114 | strcat(g_query, "admin_authid VARCHAR(64) NOT NULL,", charsmax(g_query))
115 | strcat(g_query, "admin_ip VARCHAR(22) NOT NULL,", charsmax(g_query))
116 | strcat(g_query, "created_at DATETIME NOT NULL,", charsmax(g_query))
117 | strcat(g_query, "expire_at DATETIME NOT NULL,", charsmax(g_query))
118 | strcat(g_query, "flags INTEGER NOT NULL,", charsmax(g_query))
119 | strcat(g_query, "UNIQUE INDEX authid_unique_idx (authid)", charsmax(g_query))
120 | strcat(g_query, ") CHARACTER SET utf8 COLLATE utf8_general_ci;", charsmax(g_query))
121 | }
122 |
123 | SQL_ThreadQuery(g_tuple, "handle_StorageCreated", g_query)
124 | }
125 |
126 | public handle_StorageCreated(failstate, Handle: query, error[], errnum, data[], size, Float: queuetime) {
127 | if (IsSQLQueryFailed(failstate, query, error, errnum)) {
128 | return
129 | }
130 |
131 | CA_Log(logLevel_Debug, "Table '%s' created! (queryTime: '%.3f' sec)", SQL_TBL_GAGS, queuetime)
132 |
133 | g_storageInitialized = true
134 | ExecuteForward(g_fwd_StorageInitialized, g_ret)
135 |
136 | // Load prepared data from storage
137 | new queueCounter
138 |
139 | for(new i, len = QueueSize(g_queueLoad); i < len; i++) {
140 | new authID[MAX_AUTHID_LENGTH]; QueuePopString(g_queueLoad, authID, charsmax(authID))
141 | Storage_Load(authID)
142 |
143 | ++queueCounter
144 | }
145 |
146 | if (queueCounter) {
147 | CA_Log(logLevel_Warning, "Loaded %i queue gags from DB (slow DB connection issue)", queueCounter)
148 | queueCounter = 0
149 | }
150 |
151 | // Save prepared data to storage
152 | for(new i, len = QueueSize(g_queueSave); i < len; i++) {
153 | new gagData[gagData_s]; QueuePopArray(g_queueSave, gagData, sizeof(gagData))
154 |
155 | Storage_Save(gagData[gd_name], gagData[gd_authID], gagData[gd_IP],
156 | gagData[gd_reason][r_name], gagData[gd_adminName], gagData[gd_adminAuthID],
157 | gagData[gd_adminIP], gagData[gd_expireAt], gagData[gd_reason][r_flags]
158 | )
159 |
160 | ++queueCounter
161 | }
162 |
163 | if (queueCounter) {
164 | CA_Log(logLevel_Warning, "Saved %i queue gags to DB (slow DB connection issue)", queueCounter)
165 | queueCounter = 0
166 | }
167 | }
168 |
169 |
170 | Storage_Save(const name[], const authID[], const IP[],
171 | const reason[], const adminName[], const adminAuthID[],
172 | const adminIP[], const expireAt, const flags) {
173 |
174 | if (!g_storageInitialized) {
175 | new gagData[gagData_s]; {
176 | copy(gagData[gd_name], charsmax(gagData[gd_name]), name)
177 | copy(gagData[gd_authID], charsmax(gagData[gd_authID]), authID)
178 | copy(gagData[gd_IP], charsmax(gagData[gd_IP]), IP)
179 |
180 | copy(gagData[gd_adminName], charsmax(gagData[gd_adminName]), adminName)
181 | copy(gagData[gd_adminAuthID], charsmax(gagData[gd_adminAuthID]), adminAuthID)
182 | copy(gagData[gd_adminIP], charsmax(gagData[gd_adminIP]), adminIP)
183 |
184 | copy(gagData[gd_reason][r_name], charsmax(gagData[r_name]), reason)
185 | gagData[gd_reason][r_flags] = gag_flags_s: flags
186 |
187 | gagData[gd_expireAt] = expireAt
188 | }
189 |
190 | QueuePushArray(g_queueSave, gagData)
191 |
192 | return
193 | }
194 |
195 | new name_safe[MAX_NAME_LENGTH * 2]
196 | SQL_QuoteString(Empty_Handle, name_safe, charsmax(name_safe), name)
197 |
198 | new reason_safe[MAX_REASON_LENGTH * 2]
199 | SQL_QuoteString(Empty_Handle, reason_safe, charsmax(reason_safe), reason)
200 |
201 | new adminName_safe[MAX_NAME_LENGTH * 2]
202 | SQL_QuoteString(Empty_Handle, adminName_safe, charsmax(adminName_safe), adminName)
203 |
204 | // TODO: Optimize this EPIC QUERY
205 | formatex(g_query, charsmax(g_query), "INSERT INTO %s ", SQL_TBL_GAGS); {
206 | strcat(g_query, "( name,authid,ip,", charsmax(g_query))
207 | strcat(g_query, "reason,admin_name,admin_authid,", charsmax(g_query))
208 | strcat(g_query, "admin_ip,created_at,expire_at,flags )", charsmax(g_query))
209 |
210 | strcat(g_query, fmt(" VALUES ( '%s',", name_safe), charsmax(g_query))
211 | strcat(g_query, fmt("'%s',", authID), charsmax(g_query))
212 | strcat(g_query, fmt("'%s',", IP), charsmax(g_query))
213 | strcat(g_query, fmt("'%s',", reason_safe), charsmax(g_query))
214 | strcat(g_query, fmt("'%s',", adminName_safe), charsmax(g_query))
215 | strcat(g_query, fmt("'%s',", adminAuthID), charsmax(g_query))
216 | strcat(g_query, fmt("'%s',", adminIP), charsmax(g_query))
217 | strcat(g_query, fmt("NOW(),"), charsmax(g_query))
218 | strcat(g_query, fmt("FROM_UNIXTIME(%i),", expireAt), charsmax(g_query))
219 | strcat(g_query, fmt("%i ) ", flags), charsmax(g_query))
220 | strcat(g_query, "ON DUPLICATE KEY UPDATE ", charsmax(g_query))
221 | strcat(g_query, fmt("name='%s',", name_safe), charsmax(g_query))
222 | strcat(g_query, fmt("ip='%s',", IP), charsmax(g_query))
223 | strcat(g_query, fmt("reason='%s',", reason_safe), charsmax(g_query))
224 | strcat(g_query, fmt("admin_name='%s',", adminName_safe), charsmax(g_query))
225 | strcat(g_query, fmt("admin_authid='%s',", adminAuthID), charsmax(g_query))
226 | strcat(g_query, fmt("admin_ip='%s',", adminIP), charsmax(g_query))
227 | strcat(g_query, "created_at=NOW(),", charsmax(g_query))
228 | strcat(g_query, fmt("expire_at=FROM_UNIXTIME(%i),", expireAt), charsmax(g_query))
229 | strcat(g_query, fmt("flags=%i; ", flags), charsmax(g_query))
230 | }
231 |
232 | SQL_ThreadQuery(g_tuple, "handle_Saved", g_query)
233 | }
234 |
235 | public handle_Saved(failstate, Handle: query, error[], errnum, data[], size, Float: queuetime) {
236 | if (IsSQLQueryFailed(failstate, query, error, errnum)) {
237 | return
238 | }
239 |
240 | formatex(g_query, charsmax(g_query), "SELECT \
241 | name,authid,ip,reason,\
242 | admin_name,admin_authid,admin_ip,\
243 | UNIX_TIMESTAMP(created_at),UNIX_TIMESTAMP(expire_at),flags")
244 | strcat(g_query, fmt(" FROM %s", SQL_TBL_GAGS), charsmax(g_query))
245 | strcat(g_query, fmt(" WHERE id=%i;", SQL_GetInsertId(query)), charsmax(g_query))
246 |
247 | SQL_ThreadQuery(g_tuple, "handle_SavedResult", g_query)
248 | }
249 |
250 | public handle_SavedResult(failstate, Handle: query, error[], errnum, data[], size, Float: queuetime) {
251 | if (IsSQLQueryFailed(failstate, query, error, errnum)) {
252 | return
253 | }
254 |
255 | enum { res_name, res_authid, res_ip, res_reason,
256 | res_admin_name, res_admin_authid, res_admin_ip,
257 | res_created_at, res_expire_at, res_flags
258 | }
259 |
260 | new name[MAX_NAME_LENGTH]; SQL_ReadResult(query, res_name, name, charsmax(name))
261 | new authID[MAX_AUTHID_LENGTH]; SQL_ReadResult(query, res_authid, authID, charsmax(authID))
262 | new IP[MAX_IP_LENGTH]; SQL_ReadResult(query, res_ip, IP, charsmax(IP))
263 | new reason[MAX_REASON_LENGTH]; SQL_ReadResult(query, res_reason, reason, charsmax(reason))
264 |
265 | new adminName[MAX_NAME_LENGTH]; SQL_ReadResult(query, res_admin_name, adminName, charsmax(adminName))
266 | new adminAuthID[MAX_AUTHID_LENGTH]; SQL_ReadResult(query, res_admin_authid, adminAuthID, charsmax(adminAuthID))
267 | new adminIP[MAX_IP_LENGTH]; SQL_ReadResult(query, res_admin_ip, adminIP, charsmax(adminIP))
268 |
269 | new createdAt = SQL_ReadResult(query, res_created_at)
270 | new expireAt = SQL_ReadResult(query, res_expire_at)
271 | new flags = SQL_ReadResult(query, res_flags)
272 |
273 | CA_Log(logLevel_Debug, "Player gag saved {'%s', '%s', '%s', '%s', '%s', '%s', '%s', %i, %i, %i} (queryTime: '%.3f' sec)", \
274 | name, authID, IP, reason, adminName, adminAuthID, adminIP, createdAt, expireAt, flags,\
275 | queuetime \
276 | )
277 |
278 | ExecuteForward(g_fwd_StorageSaved, g_ret,
279 | name, authID, IP, reason,
280 | adminName, adminAuthID, adminIP,
281 | createdAt, expireAt, flags
282 | )
283 | }
284 |
285 | Storage_Load(const authID[]) {
286 | if (!g_storageInitialized) {
287 | QueuePushString(g_queueLoad, authID)
288 |
289 | return
290 | }
291 |
292 | formatex(g_query, charsmax(g_query), "SELECT name, authid, ip, reason,\
293 | admin_name, admin_authid, admin_ip, \
294 | UNIX_TIMESTAMP(created_at), UNIX_TIMESTAMP(expire_at), flags FROM %s", SQL_TBL_GAGS); {
295 | strcat(g_query, fmt(" WHERE (authid = '%s')", authID), charsmax(g_query))
296 | strcat(g_query, " AND ( expire_at = FROM_UNIXTIME(9999999999) OR (expire_at > NOW()) ) LIMIT 1", charsmax(g_query))
297 | }
298 |
299 | SQL_ThreadQuery(g_tuple, "handle_Loaded", g_query)
300 | }
301 |
302 | public handle_Loaded(failstate, Handle: query, error[], errnum, data[], size, Float: queuetime) {
303 | if (IsSQLQueryFailed(failstate, query, error, errnum)) {
304 | return
305 | }
306 |
307 | enum { res_name, res_authid, res_ip, res_reason,
308 | res_admin_name, res_admin_authid, res_admin_ip,
309 | res_created_at, res_expire_at, res_flags
310 | }
311 |
312 | new bool: found = (SQL_NumResults(query) != 0)
313 |
314 | if (!found) {
315 | return
316 | }
317 |
318 | new name[MAX_NAME_LENGTH]; SQL_ReadResult(query, res_name, name, charsmax(name))
319 | new authID[MAX_AUTHID_LENGTH]; SQL_ReadResult(query, res_authid, authID, charsmax(authID))
320 | new IP[MAX_IP_LENGTH]; SQL_ReadResult(query, res_ip, IP, charsmax(IP))
321 | new reason[MAX_REASON_LENGTH]; SQL_ReadResult(query, res_reason, reason, charsmax(reason))
322 |
323 | new adminName[MAX_NAME_LENGTH]; SQL_ReadResult(query, res_admin_name, adminName, charsmax(adminName))
324 | new adminAuthID[MAX_AUTHID_LENGTH]; SQL_ReadResult(query, res_admin_authid, adminAuthID, charsmax(adminAuthID))
325 | new adminIP[MAX_IP_LENGTH]; SQL_ReadResult(query, res_admin_ip, adminIP, charsmax(adminIP))
326 |
327 | new createdAt = SQL_ReadResult(query, res_created_at)
328 | new expireAt = SQL_ReadResult(query, res_expire_at)
329 | new flags = SQL_ReadResult(query, res_flags)
330 |
331 | CA_Log(logLevel_Debug, "Player gag loaded {'%s', '%s', '%s', '%s', '%s', '%s', '%s', %i, %i, %i} (queryTime: '%.3f' sec)", \
332 | name, authID, IP, reason, adminName, adminAuthID, adminIP, createdAt, expireAt, flags,\
333 | queuetime \
334 | )
335 |
336 | ExecuteForward(g_fwd_StorageLoaded, g_ret,
337 | name, authID, IP, reason,
338 | adminName, adminAuthID, adminIP,
339 | createdAt, expireAt, flags
340 | )
341 | }
342 |
343 | Storage_Remove(const authID[]) {
344 | if (!g_storageInitialized || g_tuple == Empty_Handle) {
345 | CA_Log(logLevel_Warning, "Storage_Remove(): Storage connection not initialized. Query not executed. (g_storageInitialized=%i, g_tuple=%i)",
346 | g_storageInitialized, g_tuple
347 | )
348 |
349 | return
350 | }
351 |
352 | formatex(g_query, charsmax(g_query), "DELETE FROM %s ", SQL_TBL_GAGS); {
353 | strcat(g_query, fmt("WHERE (authid = '%s')", authID), charsmax(g_query))
354 | }
355 |
356 | SQL_ThreadQuery(g_tuple, "handle_Removed", g_query)
357 | }
358 |
359 | public handle_Removed(failstate, Handle: query, error[], errnum, data[], size, Float: queuetime) {
360 | if (IsSQLQueryFailed(failstate, query, error, errnum)) {
361 | return
362 | }
363 |
364 | CA_Log(logLevel_Debug, "Player gag removed { } (queryTime: '%.3f' sec)", \
365 | queuetime \
366 | )
367 |
368 | ExecuteForward(g_fwd_StorageRemoved, g_ret)
369 | }
370 |
--------------------------------------------------------------------------------
/cstrike/addons/amxmodx/scripting/ChatAdditions/Storage/CA_Storage_GameCMS.sma:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | #include
6 |
7 | #include
8 | #include
9 | #include
10 |
11 | #pragma dynamic 131072
12 | #pragma tabsize 4
13 |
14 | #pragma reqlib mysql
15 | #if !defined AMXMODX_NOAUTOLOAD
16 | #pragma loadlib mysql
17 | #endif
18 |
19 | new const SQL_TBL_GAGS[] = "comms"
20 |
21 | const QUERY_LENGTH = 4096
22 | const MAX_REASON_LENGTH = 256
23 | new g_query[QUERY_LENGTH]
24 |
25 | new Handle: g_tuple = Empty_Handle
26 | new Queue: g_queueLoad = Invalid_Queue,
27 | Queue: g_queueSave = Invalid_Queue
28 |
29 | new g_serverID = -1
30 | new g_gamecmsAdminId[MAX_PLAYERS + 1]
31 |
32 | new ca_server_address[128],
33 | ca_storage_host[64],
34 | ca_storage_user[128],
35 | ca_storage_pass[128],
36 | ca_storage_dbname[128]
37 |
38 | public stock const PluginName[] = "ChatAdditions: GameCMS storage"
39 | public stock const PluginVersion[] = CA_VERSION
40 | public stock const PluginAuthor[] = "Sergey Shorokhov"
41 | public stock const PluginURL[] = "https://github.com/ChatAdditions/"
42 | public stock const PluginDescription[] = "GameCMS (MySQL) storage provider for ChatAdditions"
43 |
44 | public plugin_init() {
45 | register_plugin(PluginName, PluginVersion, PluginAuthor)
46 |
47 | if (!SQL_SetAffinity("mysql")) {
48 | set_fail_state("Can't user 'MySQL'. Check modules.ini")
49 | }
50 |
51 | Create_CVars()
52 |
53 | AutoExecConfig(true, "CA_Storage_GameCMS", "ChatAdditions")
54 |
55 | g_queueLoad = QueueCreate(MAX_AUTHID_LENGTH)
56 | g_queueSave = QueueCreate(gagData_s)
57 |
58 | set_task_ex(6.274, "_OnConfigsExecuted")
59 | }
60 |
61 | public _OnConfigsExecuted() {
62 | g_tuple = SQL_MakeDbTuple(ca_storage_host, ca_storage_user, ca_storage_pass, ca_storage_dbname)
63 | SQL_SetCharset(g_tuple, "utf8")
64 |
65 | ServerAddress_Check()
66 | Storage_Create()
67 | }
68 |
69 | public plugin_end() {
70 | if (g_tuple != Empty_Handle) {
71 | SQL_FreeHandle(g_tuple)
72 | }
73 |
74 | QueueDestroy(g_queueLoad)
75 | QueueDestroy(g_queueSave)
76 | }
77 |
78 | public plugin_natives() {
79 | RegisterNatives()
80 | }
81 |
82 | public plugin_cfg() {
83 | RegisterForwards()
84 | }
85 |
86 | public client_putinserver(id) {
87 | if (!g_storageInitialized) {
88 | return
89 | }
90 |
91 | GameCMS_GetAdminID(id)
92 | }
93 |
94 | public client_disconnected(id) {
95 | g_gamecmsAdminId[id] = 0
96 | }
97 |
98 | Create_CVars() {
99 | bind_pcvar_string(create_cvar("ca_server_address", "",
100 | .description = "Server address in the GameCMS database"
101 | ),
102 | ca_server_address, charsmax(ca_server_address)
103 | )
104 |
105 | bind_pcvar_string(create_cvar("ca_storage_host", "127.0.0.1", FCVAR_PROTECTED,
106 | .description = "GameCMS MySQL database host address"
107 | ),
108 | ca_storage_host, charsmax(ca_storage_host)
109 | )
110 |
111 | bind_pcvar_string(create_cvar("ca_storage_user", "root", FCVAR_PROTECTED,
112 | .description = "GameCMS MySQL database user"
113 | ),
114 | ca_storage_user, charsmax(ca_storage_user)
115 | )
116 |
117 | bind_pcvar_string(create_cvar("ca_storage_pass", "", FCVAR_PROTECTED,
118 | .description = "GameCMS MySQL database host password"
119 | ),
120 | ca_storage_pass, charsmax(ca_storage_pass)
121 | )
122 |
123 | bind_pcvar_string(create_cvar("ca_storage_dbname", "players_gags", FCVAR_PROTECTED,
124 | .description = "GameCMS MySQL database name (not recommended to change)"
125 | ),
126 | ca_storage_dbname, charsmax(ca_storage_dbname)
127 | )
128 | }
129 |
130 | ServerAddress_Check() {
131 | if (ca_server_address[0] != EOS)
132 | return
133 |
134 | get_cvar_string("net_address", ca_server_address, charsmax(ca_server_address))
135 | }
136 |
137 | Storage_Create() {
138 | formatex(g_query, charsmax(g_query), "CREATE TABLE IF NOT EXISTS %s ", SQL_TBL_GAGS); {
139 | strcat(g_query, "( bid int(6) NOT NULL AUTO_INCREMENT,", charsmax(g_query))
140 | strcat(g_query, "authid varchar(32) COLLATE utf8_unicode_ci NOT NULL,", charsmax(g_query))
141 | strcat(g_query, "name varchar(32) COLLATE utf8_unicode_ci NOT NULL,", charsmax(g_query))
142 | strcat(g_query, "created int(11) NOT NULL,", charsmax(g_query))
143 | strcat(g_query, "expired int(11) NOT NULL,", charsmax(g_query))
144 | strcat(g_query, "length int(10) NOT NULL,", charsmax(g_query))
145 | strcat(g_query, "reason varchar(64) COLLATE utf8_unicode_ci NOT NULL,", charsmax(g_query))
146 | strcat(g_query, "admin_id int(6) NOT NULL,", charsmax(g_query))
147 | strcat(g_query, "admin_nick varchar(32) COLLATE utf8_unicode_ci NOT NULL,", charsmax(g_query))
148 | strcat(g_query, "server_id int(6) NOT NULL,", charsmax(g_query))
149 | strcat(g_query, "modified_by varchar(32) COLLATE utf8_unicode_ci NOT NULL,", charsmax(g_query))
150 | strcat(g_query, "type int(2) NOT NULL,", charsmax(g_query))
151 | strcat(g_query, "PRIMARY KEY (bid),", charsmax(g_query))
152 | strcat(g_query, "KEY sid (server_id),", charsmax(g_query))
153 | strcat(g_query, "KEY type (type),", charsmax(g_query))
154 | strcat(g_query, "KEY authid (authid),", charsmax(g_query))
155 | strcat(g_query, "KEY created (created),", charsmax(g_query))
156 | strcat(g_query, "KEY aid (admin_id)", charsmax(g_query))
157 | strcat(g_query, ") ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=37 ;", charsmax(g_query))
158 | }
159 |
160 | SQL_ThreadQuery(g_tuple, "handle_StorageCreated", g_query)
161 | }
162 |
163 | public handle_StorageCreated(failstate, Handle: query, error[], errnum, data[], size, Float: queuetime) {
164 | if (IsSQLQueryFailed(failstate, query, error, errnum)) {
165 | return
166 | }
167 |
168 | CA_Log(logLevel_Debug, "Table '%s' created! (queryTime: '%.3f' sec)", SQL_TBL_GAGS, queuetime)
169 | GameCMS_GetServerID()
170 | }
171 |
172 |
173 | Storage_Save(const name[], const authID[], const IP[],
174 | const reason[], const adminName[], const adminAuthID[],
175 | const adminIP[], const expireAt, const flags) {
176 |
177 | if (!g_storageInitialized) {
178 | new gagData[gagData_s]; {
179 | copy(gagData[gd_name], charsmax(gagData[gd_name]), name)
180 | copy(gagData[gd_authID], charsmax(gagData[gd_authID]), authID)
181 | copy(gagData[gd_IP], charsmax(gagData[gd_IP]), IP)
182 |
183 | copy(gagData[gd_adminName], charsmax(gagData[gd_adminName]), adminName)
184 | copy(gagData[gd_adminAuthID], charsmax(gagData[gd_adminAuthID]), adminAuthID)
185 | copy(gagData[gd_adminIP], charsmax(gagData[gd_adminIP]), adminIP)
186 |
187 | copy(gagData[gd_reason][r_name], charsmax(gagData[r_name]), reason)
188 | gagData[gd_reason][r_flags] = gag_flags_s: flags
189 |
190 | gagData[gd_expireAt] = expireAt
191 | }
192 |
193 | QueuePushArray(g_queueSave, gagData)
194 |
195 | return
196 | }
197 |
198 | #pragma unused adminIP, IP
199 | new name_safe[MAX_NAME_LENGTH * 2]
200 | SQL_QuoteString(Empty_Handle, name_safe, charsmax(name_safe), name)
201 |
202 | new reason_safe[MAX_REASON_LENGTH * 2]
203 | SQL_QuoteString(Empty_Handle, reason_safe, charsmax(reason_safe), reason)
204 |
205 | new adminName_safe[MAX_NAME_LENGTH * 2]
206 | SQL_QuoteString(Empty_Handle, adminName_safe, charsmax(adminName_safe), adminName)
207 |
208 |
209 | new admin_id = 0
210 | new admin = find_player_ex((FindPlayer_MatchUserId | FindPlayer_ExcludeBots), adminAuthID)
211 | if (admin) {
212 | admin_id = g_gamecmsAdminId[admin]
213 | }
214 |
215 | // TODO: Optimize this EPIC QUERY
216 | formatex(g_query, charsmax(g_query), "INSERT INTO %s ", SQL_TBL_GAGS); {
217 | strcat(g_query, "( authid,name,created,", charsmax(g_query))
218 | strcat(g_query, "expired,length,reason,", charsmax(g_query))
219 | strcat(g_query, "admin_id,admin_nick,server_id,modified_by,type )", charsmax(g_query))
220 |
221 |
222 | strcat(g_query, " VALUES ( ", charsmax(g_query))
223 | strcat(g_query, fmt("'%s',", authID), charsmax(g_query))
224 | strcat(g_query, fmt("'%s',", name_safe), charsmax(g_query))
225 | strcat(g_query, fmt("UNIX_TIMESTAMP(NOW()),"), charsmax(g_query))
226 | strcat(g_query, fmt("%i,", expireAt), charsmax(g_query))
227 | strcat(g_query, fmt("(%i - UNIX_TIMESTAMP(NOW())) / 60,", expireAt), charsmax(g_query))
228 | strcat(g_query, fmt("'%s',", reason_safe), charsmax(g_query))
229 | strcat(g_query, fmt("'%i',", admin_id), charsmax(g_query))
230 | strcat(g_query, fmt("'%s',", adminName_safe), charsmax(g_query))
231 | strcat(g_query, fmt("'%i',", g_serverID), charsmax(g_query))
232 | strcat(g_query, fmt("'%s',", adminName_safe), charsmax(g_query))
233 | strcat(g_query, fmt("%i ) ", CAGAGFlags_to_GCMS_Flags(gag_flags_s: flags)), charsmax(g_query))
234 | strcat(g_query, "ON DUPLICATE KEY UPDATE ", charsmax(g_query))
235 | strcat(g_query, fmt("name='%s',", name_safe), charsmax(g_query))
236 | strcat(g_query, fmt("reason='%s',", reason_safe), charsmax(g_query))
237 | strcat(g_query, fmt("admin_nick='%s',", adminName_safe), charsmax(g_query))
238 | strcat(g_query, "created=UNIX_TIMESTAMP(NOW()),", charsmax(g_query))
239 | strcat(g_query, fmt("expired=%i,", expireAt), charsmax(g_query))
240 | strcat(g_query, fmt("type=%i; ", CAGAGFlags_to_GCMS_Flags(gag_flags_s: flags)), charsmax(g_query))
241 | }
242 |
243 | SQL_ThreadQuery(g_tuple, "handle_Saved", g_query)
244 | }
245 |
246 | public handle_Saved(failstate, Handle: query, error[], errnum, data[], size, Float: queuetime) {
247 | if (IsSQLQueryFailed(failstate, query, error, errnum)) {
248 | return
249 | }
250 |
251 | formatex(g_query, charsmax(g_query), "SELECT \
252 | name,authid,reason,\
253 | admin_nick,\
254 | created,expired,type")
255 |
256 | strcat(g_query, fmt(" FROM %s", SQL_TBL_GAGS), charsmax(g_query))
257 | strcat(g_query, fmt(" WHERE bid=%i;", SQL_GetInsertId(query)), charsmax(g_query))
258 |
259 | SQL_ThreadQuery(g_tuple, "handle_SavedResult", g_query)
260 | }
261 |
262 | public handle_SavedResult(failstate, Handle: query, error[], errnum, data[], size, Float: queuetime) {
263 | if (IsSQLQueryFailed(failstate, query, error, errnum)) {
264 | return
265 | }
266 |
267 | enum { res_name, res_authid, /* res_ip, */ res_reason,
268 | res_admin_name, /* res_admin_authid, res_admin_ip, */
269 | res_created_at, res_expire_at, res_flags
270 | }
271 |
272 | new name[MAX_NAME_LENGTH]; SQL_ReadResult(query, res_name, name, charsmax(name))
273 | new authID[MAX_AUTHID_LENGTH]; SQL_ReadResult(query, res_authid, authID, charsmax(authID))
274 | new IP[MAX_IP_LENGTH]; /* SQL_ReadResult(query, res_ip, IP, charsmax(IP)) */
275 | new reason[MAX_REASON_LENGTH]; SQL_ReadResult(query, res_reason, reason, charsmax(reason))
276 |
277 | new adminName[MAX_NAME_LENGTH]; SQL_ReadResult(query, res_admin_name, adminName, charsmax(adminName))
278 | new adminAuthID[MAX_AUTHID_LENGTH]; /* SQL_ReadResult(query, res_admin_authid, adminAuthID, charsmax(adminAuthID)) */
279 | new adminIP[MAX_IP_LENGTH]; /* SQL_ReadResult(query, res_admin_ip, adminIP, charsmax(adminIP)) */
280 |
281 | // HACK: for bad DB struct
282 | new target = find_player_ex((FindPlayer_MatchAuthId | FindPlayer_ExcludeBots), authID)
283 | if (target)
284 | get_user_ip(target, IP, charsmax(IP), true)
285 |
286 | new admin = find_player_ex((FindPlayer_MatchName | FindPlayer_ExcludeBots), adminName)
287 | if (admin) {
288 | get_user_authid(admin, adminAuthID, charsmax(adminAuthID))
289 | get_user_ip(admin, adminIP, charsmax(adminIP), true)
290 | }
291 |
292 | new createdAt = SQL_ReadResult(query, res_created_at)
293 | new expireAt = SQL_ReadResult(query, res_expire_at)
294 | new flags = GCMS_FlagsTo_CAGAGFlags(SQL_ReadResult(query, res_flags))
295 |
296 | CA_Log(logLevel_Debug, "Player gag saved {'%s', '%s', '%s', '%s', '%s', '%s', '%s', %i, %i, %i} (queryTime: '%.3f' sec)", \
297 | name, authID, IP, reason, adminName, adminAuthID, adminIP, createdAt, expireAt, flags,\
298 | queuetime \
299 | )
300 |
301 | ExecuteForward(g_fwd_StorageSaved, g_ret,
302 | name, authID, IP, reason,
303 | adminName, adminAuthID, adminIP,
304 | createdAt, expireAt, flags
305 | )
306 | }
307 |
308 | Storage_Load(const authID[]) {
309 | if (!g_storageInitialized) {
310 | QueuePushString(g_queueLoad, authID)
311 |
312 | return
313 | }
314 |
315 | formatex(g_query, charsmax(g_query), "SELECT name, authid, reason,\
316 | admin_nick, \
317 | created, expired, type FROM %s", SQL_TBL_GAGS); {
318 | strcat(g_query, fmt(" WHERE (authid = '%s')", authID), charsmax(g_query))
319 | strcat(g_query, " AND (expired > UNIX_TIMESTAMP(NOW())) LIMIT 1;", charsmax(g_query))
320 | }
321 |
322 | SQL_ThreadQuery(g_tuple, "handle_Loaded", g_query)
323 | }
324 |
325 | public handle_Loaded(failstate, Handle: query, error[], errnum, data[], size, Float: queuetime) {
326 | if (IsSQLQueryFailed(failstate, query, error, errnum)) {
327 | return
328 | }
329 |
330 | enum { res_name, res_authid, /* res_ip, */res_reason,
331 | res_admin_name, /* res_admin_authid, res_admin_ip, */
332 | res_created_at, res_expire_at, res_flags
333 | }
334 |
335 | new bool: found = (SQL_NumResults(query) != 0)
336 |
337 | if (!found) {
338 | return
339 | }
340 |
341 | new name[MAX_NAME_LENGTH]; SQL_ReadResult(query, res_name, name, charsmax(name))
342 | new authID[MAX_AUTHID_LENGTH]; SQL_ReadResult(query, res_authid, authID, charsmax(authID))
343 | new IP[MAX_IP_LENGTH]; /* SQL_ReadResult(query, res_ip, IP, charsmax(IP)) */
344 | new reason[MAX_REASON_LENGTH]; SQL_ReadResult(query, res_reason, reason, charsmax(reason))
345 |
346 | new adminName[MAX_NAME_LENGTH]; SQL_ReadResult(query, res_admin_name, adminName, charsmax(adminName))
347 | new adminAuthID[MAX_AUTHID_LENGTH]; /* SQL_ReadResult(query, res_admin_authid, adminAuthID, charsmax(adminAuthID)) */
348 | new adminIP[MAX_IP_LENGTH]; /* SQL_ReadResult(query, res_admin_ip, adminIP, charsmax(adminIP)) */
349 |
350 | // HACK: for bad DB struct
351 | new target = find_player_ex((FindPlayer_MatchAuthId | FindPlayer_ExcludeBots), authID)
352 | if (target)
353 | get_user_ip(target, IP, charsmax(IP), true)
354 |
355 | new admin = find_player_ex((FindPlayer_MatchName | FindPlayer_ExcludeBots), adminName)
356 | if (admin) {
357 | get_user_authid(admin, adminAuthID, charsmax(adminAuthID))
358 | get_user_ip(admin, adminIP, charsmax(adminIP), true)
359 | }
360 |
361 | new createdAt = SQL_ReadResult(query, res_created_at)
362 | new expireAt = SQL_ReadResult(query, res_expire_at)
363 | new flags = GCMS_FlagsTo_CAGAGFlags(SQL_ReadResult(query, res_flags))
364 |
365 | CA_Log(logLevel_Debug, "Player gag loaded {'%s', '%s', '%s', '%s', '%s', '%s', '%s', %i, %i, %i} (queryTime: '%.3f' sec)", \
366 | name, authID, IP, reason, adminName, adminAuthID, adminIP, createdAt, expireAt, flags,\
367 | queuetime \
368 | )
369 |
370 | ExecuteForward(g_fwd_StorageLoaded, g_ret,
371 | name, authID, IP, reason,
372 | adminName, adminAuthID, adminIP,
373 | createdAt, expireAt, flags
374 | )
375 | }
376 |
377 | Storage_Remove(const authID[]) {
378 | if (!g_storageInitialized || g_tuple == Empty_Handle) {
379 | CA_Log(logLevel_Warning, "Storage_Remove(): Storage connection not initialized. Query not executed. (g_storageInitialized=%i, g_tuple=%i)",
380 | g_storageInitialized, g_tuple
381 | )
382 |
383 | return
384 | }
385 |
386 | formatex(g_query, charsmax(g_query), "DELETE FROM %s ", SQL_TBL_GAGS); {
387 | strcat(g_query, fmt("WHERE (authid = '%s')", authID), charsmax(g_query))
388 | }
389 |
390 | SQL_ThreadQuery(g_tuple, "handle_Removed", g_query)
391 | }
392 |
393 | public handle_Removed(failstate, Handle: query, error[], errnum, data[], size, Float: queuetime) {
394 | if (IsSQLQueryFailed(failstate, query, error, errnum)) {
395 | return
396 | }
397 |
398 | CA_Log(logLevel_Debug, "Player gag removed { } (queryTime: '%.3f' sec)", \
399 | queuetime \
400 | )
401 |
402 | ExecuteForward(g_fwd_StorageRemoved, g_ret)
403 | }
404 |
405 | GameCMS_GetServerID() {
406 | new serverAddress[2][128]
407 | explode_string(ca_server_address, ":", serverAddress, sizeof(serverAddress), charsmax(serverAddress[]))
408 |
409 | formatex(g_query, charsmax(g_query), "SELECT id FROM servers WHERE servers.ip = '%s' AND servers.port = '%s' LIMIT 1;",
410 | serverAddress[0], serverAddress[1]
411 | )
412 |
413 | SQL_ThreadQuery(g_tuple, "handle_GetServerID", g_query)
414 | }
415 |
416 | public handle_GetServerID(failstate, Handle: query, error[], errnum, data[], size, Float: queuetime) {
417 | if (IsSQLQueryFailed(failstate, query, error, errnum)) {
418 | return
419 | }
420 |
421 | new bool: found = bool: (SQL_NumResults(query) != 0)
422 |
423 | if (!found) {
424 | set_fail_state("Server `%s` not found on db.", ca_server_address)
425 |
426 | return
427 | }
428 |
429 | g_serverID = SQL_ReadResult(query, 0)
430 | CA_Log(logLevel_Debug, "Found server `%s` in db. ServerID=%i", ca_server_address, g_serverID)
431 |
432 | g_storageInitialized = true
433 | ExecuteForward(g_fwd_StorageInitialized, g_ret)
434 |
435 | // Load prepared data from storage
436 | new queueCounter
437 |
438 | for(new i, len = QueueSize(g_queueLoad); i < len; i++) {
439 | new authID[MAX_AUTHID_LENGTH]; QueuePopString(g_queueLoad, authID, charsmax(authID))
440 | Storage_Load(authID)
441 |
442 | ++queueCounter
443 | }
444 |
445 | if (queueCounter) {
446 | CA_Log(logLevel_Warning, "Loaded %i queue gags from DB (slow DB connection issue)", queueCounter)
447 | queueCounter = 0
448 | }
449 |
450 | // Save prepared data to storage
451 | for(new i, len = QueueSize(g_queueSave); i < len; i++) {
452 | new gagData[gagData_s]; QueuePopArray(g_queueSave, gagData, sizeof(gagData))
453 |
454 | Storage_Save(gagData[gd_name], gagData[gd_authID], gagData[gd_IP],
455 | gagData[gd_reason][r_name], gagData[gd_adminName], gagData[gd_adminAuthID],
456 | gagData[gd_adminIP], gagData[gd_expireAt], gagData[gd_reason][r_flags]
457 | )
458 |
459 | ++queueCounter
460 | }
461 |
462 | if (queueCounter) {
463 | CA_Log(logLevel_Warning, "Saved %i queue gags to DB (slow DB connection issue)", queueCounter)
464 | queueCounter = 0
465 | }
466 |
467 | new players[MAX_PLAYERS], count
468 | get_players_ex(players, count, .flags = (GetPlayers_ExcludeBots | GetPlayers_ExcludeHLTV))
469 |
470 | for(new i; i < count; i++) {
471 | GameCMS_GetAdminID(players[i])
472 | }
473 | }
474 |
475 | enum {
476 | GCMS_FLAG_NONE = -1,
477 | GCMS_FLAG_ALL,
478 | GCMS_FLAG_CHAT,
479 | GCMS_FLAG_VOICE
480 | }
481 |
482 | static stock gag_flags_s: GCMS_FlagsTo_CAGAGFlags(const flag) {
483 | switch (flag) {
484 | case GCMS_FLAG_NONE: return (gagFlag_Removed)
485 | case GCMS_FLAG_ALL: return (gagFlag_Say | gagFlag_SayTeam | gagFlag_Voice)
486 | case GCMS_FLAG_CHAT: return (gagFlag_Say | gagFlag_SayTeam)
487 | case GCMS_FLAG_VOICE: return (gagFlag_Voice)
488 | }
489 |
490 | CA_Log(logLevel_Warning, "[WARN]: GCMS_FlagsTo_CAGAGFlags() => Undefinded flag:%i", flag)
491 | return gagFlag_Removed
492 | }
493 |
494 | static stock CAGAGFlags_to_GCMS_Flags(const gag_flags_s: flags) {
495 | if (flags == gagFlag_Voice) {
496 | return GCMS_FLAG_VOICE
497 | }
498 | if (flags == (gagFlag_Say | gagFlag_SayTeam | gagFlag_Voice)) {
499 | return GCMS_FLAG_ALL
500 | }
501 | if (flags & (gagFlag_Say | gagFlag_SayTeam)) {
502 | return GCMS_FLAG_CHAT
503 | }
504 |
505 | return GCMS_FLAG_NONE
506 | }
507 |
508 | GameCMS_GetAdminID(const id) {
509 | new authID[MAX_AUTHID_LENGTH], name[MAX_NAME_LENGTH]
510 | get_user_authid(id, authID, charsmax(authID))
511 | get_user_name(id, name, charsmax(name))
512 |
513 | new name_safe[MAX_NAME_LENGTH * 2]
514 | SQL_QuoteString(Empty_Handle, name_safe, charsmax(name_safe), name)
515 |
516 | formatex(g_query, charsmax(g_query), "SELECT id FROM admins WHERE (name = '%s' or name = ^"%s^") LIMIT 1;",
517 | authID, name_safe
518 | )
519 |
520 | new data[1]; data[0] = id
521 | SQL_ThreadQuery(g_tuple, "handle_GetAdminID", g_query, data, sizeof(data))
522 | }
523 |
524 | public handle_GetAdminID(failstate, Handle: query, error[], errnum, data[], size, Float: queuetime) {
525 | enum { col_id }
526 |
527 | if (IsSQLQueryFailed(failstate, query, error, errnum)) {
528 | return
529 | }
530 |
531 | new bool: found = bool: (SQL_NumResults(query) != 0)
532 | if (!found) {
533 | return
534 | }
535 |
536 | g_gamecmsAdminId[data[0]] = SQL_ReadResult(query, col_id)
537 | CA_Log(logLevel_Debug, "Found admin `%N` in gameCMS DB. admins.id=%i", data[0], g_gamecmsAdminId[data[0]])
538 | }
539 |
--------------------------------------------------------------------------------
/cstrike/addons/amxmodx/scripting/ChatAdditions/Storage/CA_Storage_PGBans.sma:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | #include
6 |
7 | #include
8 | #include
9 | #include
10 |
11 | #pragma dynamic 131072
12 | #pragma tabsize 4
13 |
14 | #pragma reqlib mysql
15 | #if !defined AMXMODX_NOAUTOLOAD
16 | #pragma loadlib mysql
17 | #endif
18 |
19 | new const SQL_TBL_GAGS[] = "pgb_comms"
20 |
21 | const QUERY_LENGTH = 4096
22 | const MAX_REASON_LENGTH = 256
23 | new g_query[QUERY_LENGTH]
24 |
25 | new Handle: g_tuple = Empty_Handle
26 | new Queue: g_queueLoad = Invalid_Queue,
27 | Queue: g_queueSave = Invalid_Queue
28 |
29 | new pgb_storage_host[33],
30 | pgb_storage_user[33],
31 | pgb_storage_pass[64],
32 | pgb_storage_dbname[33]
33 |
34 | public stock const PluginName[] = "ChatAdditions: PGBans storage"
35 | public stock const PluginVersion[] = CA_VERSION
36 | public stock const PluginAuthor[] = "Sergey Shorokhov"
37 | public stock const PluginURL[] = "https://github.com/ChatAdditions/"
38 | public stock const PluginDescription[] = "PGBans (MySQL) storage provider for ChatAdditions"
39 |
40 | public plugin_init() {
41 | register_plugin(PluginName, PluginVersion, PluginAuthor)
42 |
43 | if (!SQL_SetAffinity("mysql")) {
44 | set_fail_state("Can't user 'MySQL'. Check modules.ini")
45 | }
46 |
47 | Create_CVars()
48 |
49 | AutoExecConfig(true, "CA_Storage_PGBans", "ChatAdditions")
50 |
51 | g_queueLoad = QueueCreate(MAX_AUTHID_LENGTH)
52 | g_queueSave = QueueCreate(gagData_s)
53 |
54 | set_task_ex(6.274, "_OnConfigsExecuted")
55 | }
56 |
57 | public _OnConfigsExecuted() {
58 | g_tuple = SQL_MakeDbTuple(pgb_storage_host, pgb_storage_user, pgb_storage_pass, pgb_storage_dbname)
59 |
60 | Storage_Create()
61 | }
62 |
63 | public plugin_end() {
64 | if (g_tuple != Empty_Handle) {
65 | SQL_FreeHandle(g_tuple)
66 | }
67 |
68 | QueueDestroy(g_queueLoad)
69 | QueueDestroy(g_queueSave)
70 | }
71 |
72 | public plugin_natives() {
73 | RegisterNatives()
74 | }
75 |
76 | public plugin_cfg() {
77 | RegisterForwards()
78 | }
79 |
80 | Create_CVars() {
81 | bind_pcvar_string(create_cvar("pgb_storage_host", "127.0.0.1", FCVAR_PROTECTED,
82 | .description = "PGBans MySQL database host address"
83 | ),
84 | pgb_storage_host, charsmax(pgb_storage_host)
85 | )
86 |
87 | bind_pcvar_string(create_cvar("pgb_storage_user", "root", FCVAR_PROTECTED,
88 | .description = "PGBans MySQL database user"
89 | ),
90 | pgb_storage_user, charsmax(pgb_storage_user)
91 | )
92 |
93 | bind_pcvar_string(create_cvar("pgb_storage_pass", "pass", FCVAR_PROTECTED,
94 | .description = "PGBans MySQL database host password"
95 | ),
96 | pgb_storage_pass, charsmax(pgb_storage_pass)
97 | )
98 |
99 | bind_pcvar_string(create_cvar("pgb_storage_dbname", "db", FCVAR_PROTECTED,
100 | .description = "PGBans MySQL database name"
101 | ),
102 | pgb_storage_dbname, charsmax(pgb_storage_dbname)
103 | )
104 | }
105 |
106 | Storage_Create() {
107 | formatex(g_query, charsmax(g_query), "CREATE TABLE IF NOT EXISTS %s ", SQL_TBL_GAGS); {
108 | strcat(g_query, "( id INTEGER PRIMARY KEY AUTO_INCREMENT,", charsmax(g_query))
109 | strcat(g_query, "name VARCHAR(32) NOT NULL,", charsmax(g_query))
110 | strcat(g_query, "authid VARCHAR(64) NOT NULL,", charsmax(g_query))
111 | strcat(g_query, "ip VARCHAR(22) NOT NULL,", charsmax(g_query))
112 | strcat(g_query, "reason VARCHAR(256) NOT NULL,", charsmax(g_query))
113 | strcat(g_query, "admin_name VARCHAR(32) NOT NULL,", charsmax(g_query))
114 | strcat(g_query, "admin_authid VARCHAR(64) NOT NULL,", charsmax(g_query))
115 | strcat(g_query, "admin_ip VARCHAR(22) NOT NULL,", charsmax(g_query))
116 | strcat(g_query, "created_at DATETIME NOT NULL,", charsmax(g_query))
117 | strcat(g_query, "expire_at DATETIME NOT NULL,", charsmax(g_query))
118 | strcat(g_query, "flags INTEGER NOT NULL,", charsmax(g_query))
119 | strcat(g_query, "UNIQUE INDEX authid_unique_idx (authid)", charsmax(g_query))
120 | strcat(g_query, ") CHARACTER SET utf8 COLLATE utf8_general_ci;", charsmax(g_query))
121 | }
122 |
123 | SQL_ThreadQuery(g_tuple, "handle_StorageCreated", g_query)
124 | }
125 |
126 | public handle_StorageCreated(failstate, Handle: query, error[], errnum, data[], size, Float:queuetime) {
127 | if (IsSQLQueryFailed(failstate, query, error, errnum)) {
128 | return
129 | }
130 |
131 | CA_Log(logLevel_Debug, "Table '%s' created! (queryTime: '%.3f' sec)", SQL_TBL_GAGS, queuetime)
132 |
133 | g_storageInitialized = true
134 | ExecuteForward(g_fwd_StorageInitialized, g_ret)
135 |
136 | // Load prepared data from storage
137 | new queueCounter
138 |
139 | for(new i, len = QueueSize(g_queueLoad); i < len; i++) {
140 | new authID[MAX_AUTHID_LENGTH]; QueuePopString(g_queueLoad, authID, charsmax(authID))
141 | Storage_Load(authID)
142 |
143 | ++queueCounter
144 | }
145 |
146 | if (queueCounter) {
147 | CA_Log(logLevel_Info, "Loaded %i queue gags from DB (slow DB connection issue)", queueCounter)
148 | queueCounter = 0
149 | }
150 |
151 | // Save prepared data to storage
152 | for(new i, len = QueueSize(g_queueSave); i < len; i++) {
153 | new gagData[gagData_s]; QueuePopArray(g_queueSave, gagData, sizeof(gagData))
154 |
155 | Storage_Save(gagData[gd_name], gagData[gd_authID], gagData[gd_IP],
156 | gagData[gd_reason][r_name], gagData[gd_adminName], gagData[gd_adminAuthID],
157 | gagData[gd_adminIP], gagData[gd_expireAt], gagData[gd_reason][r_flags]
158 | )
159 |
160 | ++queueCounter
161 | }
162 |
163 | if (queueCounter) {
164 | CA_Log(logLevel_Info, "Saved %i queue gags to DB (slow DB connection issue)", queueCounter)
165 | queueCounter = 0
166 | }
167 | }
168 |
169 |
170 | Storage_Save(const name[], const authID[], const IP[],
171 | const reason[], const adminName[], const adminAuthID[],
172 | const adminIP[], const expireAt, const flags) {
173 |
174 | if (!g_storageInitialized) {
175 | new gagData[gagData_s]; {
176 | copy(gagData[gd_name], charsmax(gagData[gd_name]), name)
177 | copy(gagData[gd_authID], charsmax(gagData[gd_authID]), authID)
178 | copy(gagData[gd_IP], charsmax(gagData[gd_IP]), IP)
179 |
180 | copy(gagData[gd_adminName], charsmax(gagData[gd_adminName]), adminName)
181 | copy(gagData[gd_adminAuthID], charsmax(gagData[gd_adminAuthID]), adminAuthID)
182 | copy(gagData[gd_adminIP], charsmax(gagData[gd_adminIP]), adminIP)
183 |
184 | copy(gagData[gd_reason][r_name], charsmax(gagData[r_name]), reason)
185 | gagData[gd_reason][r_flags] = gag_flags_s: flags
186 |
187 | gagData[gd_expireAt] = expireAt
188 | }
189 |
190 | QueuePushArray(g_queueSave, gagData)
191 |
192 | return
193 | }
194 |
195 | new name_safe[MAX_NAME_LENGTH * 2]
196 | SQL_QuoteString(Empty_Handle, name_safe, charsmax(name_safe), name)
197 |
198 | new reason_safe[MAX_REASON_LENGTH * 2]
199 | SQL_QuoteString(Empty_Handle, reason_safe, charsmax(reason_safe), reason)
200 |
201 | new adminName_safe[MAX_NAME_LENGTH * 2]
202 | SQL_QuoteString(Empty_Handle, adminName_safe, charsmax(adminName_safe), adminName)
203 |
204 | // TODO: Optimize this EPIC QUERY
205 | formatex(g_query, charsmax(g_query), "INSERT INTO %s ", SQL_TBL_GAGS); {
206 | strcat(g_query, "( name,authid,ip,", charsmax(g_query))
207 | strcat(g_query, "reason,admin_name,admin_authid,", charsmax(g_query))
208 | strcat(g_query, "admin_ip,created_at,expire_at,flags )", charsmax(g_query))
209 |
210 | strcat(g_query, fmt(" VALUES ( '%s',", name_safe), charsmax(g_query))
211 | strcat(g_query, fmt("'%s',", authID), charsmax(g_query))
212 | strcat(g_query, fmt("'%s',", IP), charsmax(g_query))
213 | strcat(g_query, fmt("'%s',", reason_safe), charsmax(g_query))
214 | strcat(g_query, fmt("'%s',", adminName_safe), charsmax(g_query))
215 | strcat(g_query, fmt("'%s',", adminAuthID), charsmax(g_query))
216 | strcat(g_query, fmt("'%s',", adminIP), charsmax(g_query))
217 | strcat(g_query, fmt("NOW(),"), charsmax(g_query))
218 | strcat(g_query, fmt("FROM_UNIXTIME(%i),", expireAt), charsmax(g_query))
219 | strcat(g_query, fmt("%i ) ", flags), charsmax(g_query))
220 | strcat(g_query, "ON DUPLICATE KEY UPDATE ", charsmax(g_query))
221 | strcat(g_query, fmt("name='%s',", name_safe), charsmax(g_query))
222 | strcat(g_query, fmt("ip='%s',", IP), charsmax(g_query))
223 | strcat(g_query, fmt("reason='%s',", reason_safe), charsmax(g_query))
224 | strcat(g_query, fmt("admin_name='%s',", adminName_safe), charsmax(g_query))
225 | strcat(g_query, fmt("admin_authid='%s',", adminAuthID), charsmax(g_query))
226 | strcat(g_query, fmt("admin_ip='%s',", adminIP), charsmax(g_query))
227 | strcat(g_query, "created_at=NOW(),", charsmax(g_query))
228 | strcat(g_query, fmt("expire_at=FROM_UNIXTIME(%i),", expireAt), charsmax(g_query))
229 | strcat(g_query, fmt("flags=%i;", flags), charsmax(g_query))
230 | }
231 |
232 | SQL_ThreadQuery(g_tuple, "handle_Saved", g_query)
233 | }
234 |
235 | public handle_Saved(failstate, Handle: query, error[], errnum, data[], size, Float: queuetime) {
236 | if (IsSQLQueryFailed(failstate, query, error, errnum)) {
237 | return
238 | }
239 |
240 | formatex(g_query, charsmax(g_query), "SELECT \
241 | name,authid,ip,reason,\
242 | admin_name,admin_authid,admin_ip,\
243 | UNIX_TIMESTAMP(created_at),UNIX_TIMESTAMP(expire_at),flags")
244 | strcat(g_query, fmt(" FROM %s", SQL_TBL_GAGS), charsmax(g_query))
245 | strcat(g_query, fmt(" WHERE id=%i;", SQL_GetInsertId(query)), charsmax(g_query))
246 |
247 | SQL_ThreadQuery(g_tuple, "handle_SavedResult", g_query)
248 | }
249 |
250 | public handle_SavedResult(failstate, Handle: query, error[], errnum, data[], size, Float: queuetime) {
251 | if (IsSQLQueryFailed(failstate, query, error, errnum)) {
252 | return
253 | }
254 |
255 | enum { res_name, res_authid, res_ip, res_reason,
256 | res_admin_name, res_admin_authid, res_admin_ip,
257 | res_created_at, res_expire_at, res_flags
258 | }
259 |
260 | new name[MAX_NAME_LENGTH]; SQL_ReadResult(query, res_name, name, charsmax(name))
261 | new authID[MAX_AUTHID_LENGTH]; SQL_ReadResult(query, res_authid, authID, charsmax(authID))
262 | new IP[MAX_IP_LENGTH]; SQL_ReadResult(query, res_ip, IP, charsmax(IP))
263 | new reason[MAX_REASON_LENGTH]; SQL_ReadResult(query, res_reason, reason, charsmax(reason))
264 |
265 | new adminName[MAX_NAME_LENGTH]; SQL_ReadResult(query, res_admin_name, adminName, charsmax(adminName))
266 | new adminAuthID[MAX_AUTHID_LENGTH]; SQL_ReadResult(query, res_admin_authid, adminAuthID, charsmax(adminAuthID))
267 | new adminIP[MAX_IP_LENGTH]; SQL_ReadResult(query, res_admin_ip, adminIP, charsmax(adminIP))
268 |
269 | new createdAt = SQL_ReadResult(query, res_created_at)
270 | new expireAt = SQL_ReadResult(query, res_expire_at)
271 | new flags = SQL_ReadResult(query, res_flags)
272 |
273 | CA_Log(logLevel_Debug, "Player gag saved {'%s', '%s', '%s', '%s', '%s', '%s', '%s', %i, %i, %i} (queryTime: '%.3f' sec)", \
274 | name, authID, IP, reason, adminName, adminAuthID, adminIP, createdAt, expireAt, flags,\
275 | queuetime \
276 | )
277 |
278 | ExecuteForward(g_fwd_StorageSaved, g_ret,
279 | name, authID, IP, reason,
280 | adminName, adminAuthID, adminIP,
281 | createdAt, expireAt, flags
282 | )
283 | }
284 |
285 | Storage_Load(const authID[]) {
286 | if (!g_storageInitialized) {
287 | QueuePushString(g_queueLoad, authID)
288 |
289 | return
290 | }
291 |
292 | formatex(g_query, charsmax(g_query), "SELECT name, authid, ip, reason,\
293 | admin_name, admin_authid, admin_ip, \
294 | UNIX_TIMESTAMP(created_at), UNIX_TIMESTAMP(expire_at), flags FROM %s", SQL_TBL_GAGS); {
295 | strcat(g_query, fmt(" WHERE (authid = '%s')", authID), charsmax(g_query))
296 | strcat(g_query, " AND ( expire_at = FROM_UNIXTIME(9999999999) OR (expire_at > NOW())) LIMIT 1", charsmax(g_query))
297 | }
298 |
299 | SQL_ThreadQuery(g_tuple, "handle_Loaded", g_query)
300 | }
301 |
302 | public handle_Loaded(failstate, Handle: query, error[], errnum, data[], size, Float:queuetime) {
303 | if (IsSQLQueryFailed(failstate, query, error, errnum)) {
304 | return
305 | }
306 |
307 | enum { res_name, res_authid, res_ip, res_reason,
308 | res_admin_name, res_admin_authid, res_admin_ip,
309 | res_created_at, res_expire_at, res_flags
310 | }
311 |
312 | new bool: found = (SQL_NumResults(query) != 0)
313 |
314 | if (!found) {
315 | return
316 | }
317 |
318 | new name[MAX_NAME_LENGTH]; SQL_ReadResult(query, res_name, name, charsmax(name))
319 | new authID[MAX_AUTHID_LENGTH]; SQL_ReadResult(query, res_authid, authID, charsmax(authID))
320 | new IP[MAX_IP_LENGTH]; SQL_ReadResult(query, res_ip, IP, charsmax(IP))
321 | new reason[MAX_REASON_LENGTH]; SQL_ReadResult(query, res_reason, reason, charsmax(reason))
322 |
323 | new adminName[MAX_NAME_LENGTH]; SQL_ReadResult(query, res_admin_name, adminName, charsmax(adminName))
324 | new adminAuthID[MAX_AUTHID_LENGTH]; SQL_ReadResult(query, res_admin_authid, adminAuthID, charsmax(adminAuthID))
325 | new adminIP[MAX_IP_LENGTH]; SQL_ReadResult(query, res_admin_ip, adminIP, charsmax(adminIP))
326 |
327 | new createdAt = SQL_ReadResult(query, res_created_at)
328 | new expireAt = SQL_ReadResult(query, res_expire_at)
329 | new flags = SQL_ReadResult(query, res_flags)
330 |
331 | CA_Log(logLevel_Debug, "Player gag loaded {'%s', '%s', '%s', '%s', '%s', '%s', '%s', %i, %i, %i} (queryTime: '%.3f' sec)", \
332 | name, authID, IP, reason, adminName, adminAuthID, adminIP, createdAt, expireAt, flags, \
333 | queuetime \
334 | )
335 |
336 | ExecuteForward(g_fwd_StorageLoaded, g_ret,
337 | name, authID, IP, reason,
338 | adminName, adminAuthID, adminIP,
339 | createdAt, expireAt, flags
340 | )
341 | }
342 |
343 | Storage_Remove(const authID[]) {
344 | if (!g_storageInitialized || g_tuple == Empty_Handle) {
345 | CA_Log(logLevel_Warning, "Storage_Remove(): Storage connection not initialized. Query not executed. (g_storageInitialized=%i, g_tuple=%i)",
346 | g_storageInitialized, g_tuple
347 | )
348 |
349 | return
350 | }
351 |
352 | formatex(g_query, charsmax(g_query), "DELETE FROM %s ", SQL_TBL_GAGS); {
353 | strcat(g_query, fmt("WHERE (authid = '%s')", authID), charsmax(g_query))
354 | }
355 |
356 | SQL_ThreadQuery(g_tuple, "handle_Removed", g_query)
357 | }
358 |
359 | public handle_Removed(failstate, Handle: query, error[], errnum, data[], size, Float: queuetime) {
360 | if (IsSQLQueryFailed(failstate, query, error, errnum)) {
361 | return
362 | }
363 |
364 | CA_Log(logLevel_Debug, "Player gag removed { } (queryTime: '%.3f' sec)", \
365 | queuetime \
366 | )
367 |
368 | ExecuteForward(g_fwd_StorageRemoved, g_ret)
369 | }
370 |
--------------------------------------------------------------------------------
/cstrike/addons/amxmodx/scripting/ChatAdditions/Storage/CA_Storage_SQLite.sma:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include
5 | #include
6 |
7 | #pragma dynamic 131072
8 | #pragma tabsize 4
9 |
10 | #pragma reqlib sqlite
11 | #if !defined AMXMODX_NOAUTOLOAD
12 | #pragma loadlib sqlite
13 | #endif
14 |
15 | new const SQL_DBNAME[] = "ChatAdditions"
16 | new const SQL_TBL_GAGS[] = "players_gags"
17 |
18 | const QUERY_LENGTH = 4096
19 | const MAX_REASON_LENGTH = 256
20 |
21 | new Handle: g_tuple = Empty_Handle
22 |
23 | public stock const PluginName[] = "ChatAdditions: SQLite storage"
24 | public stock const PluginVersion[] = CA_VERSION
25 | public stock const PluginAuthor[] = "Sergey Shorokhov"
26 | public stock const PluginURL[] = "https://github.com/ChatAdditions/"
27 | public stock const PluginDescription[] = "SQLite storage provider for ChatAdditions"
28 |
29 | public plugin_init() {
30 | register_plugin(PluginName, PluginVersion, PluginAuthor)
31 |
32 | if (!SQL_SetAffinity("sqlite")) {
33 | set_fail_state("Can't user 'SQLite'. Check modules.ini")
34 | }
35 |
36 | g_tuple = SQL_MakeDbTuple("", "", "", SQL_DBNAME)
37 |
38 | Storage_Create()
39 | }
40 |
41 | public plugin_end() {
42 | if (g_tuple != Empty_Handle) {
43 | SQL_FreeHandle(g_tuple)
44 | }
45 | }
46 |
47 | public plugin_natives() {
48 | RegisterNatives()
49 | }
50 |
51 | public plugin_cfg() {
52 | RegisterForwards()
53 | }
54 |
55 | Storage_Create() {
56 | new query[QUERY_LENGTH]
57 |
58 | formatex(query, charsmax(query), "CREATE TABLE IF NOT EXISTS %s ", SQL_TBL_GAGS); {
59 | strcat(query, "( id INTEGER PRIMARY KEY AUTOINCREMENT,", charsmax(query))
60 | strcat(query, "name VARCHAR NOT NULL,", charsmax(query))
61 | strcat(query, "authid VARCHAR NOT NULL,", charsmax(query))
62 | strcat(query, "ip VARCHAR NOT NULL,", charsmax(query))
63 | strcat(query, "reason VARCHAR NOT NULL,", charsmax(query))
64 | strcat(query, "admin_name VARCHAR NOT NULL,", charsmax(query))
65 | strcat(query, "admin_authid VARCHAR NOT NULL,", charsmax(query))
66 | strcat(query, "admin_ip VARCHAR NOT NULL,", charsmax(query))
67 | strcat(query, "created_at DATETIME NOT NULL,", charsmax(query))
68 | strcat(query, "expire_at DATETIME NOT NULL,", charsmax(query))
69 | strcat(query, "flags INTEGER NOT NULL", charsmax(query))
70 | strcat(query, ");", charsmax(query))
71 | }
72 | strcat(query, fmt("CREATE UNIQUE INDEX IF NOT EXISTS authid_unique_idx ON %s (authid)", SQL_TBL_GAGS), charsmax(query))
73 |
74 | SQL_ThreadQuery(g_tuple, "handle_StorageCreated", query)
75 | }
76 |
77 | public handle_StorageCreated(failstate, Handle: query, error[], errnum, data[], size, Float: queuetime) {
78 | if (IsSQLQueryFailed(failstate, query, error, errnum)) {
79 | return
80 | }
81 |
82 | CA_Log(logLevel_Debug, "Table '%s' created! (queryTime: '%.3f' sec)", SQL_TBL_GAGS, queuetime)
83 |
84 | ExecuteForward(g_fwd_StorageInitialized, g_ret)
85 | }
86 |
87 | Storage_Save(const name[], const authID[], const IP[],
88 | const reason[], const adminName[], const adminAuthID[],
89 | const adminIP[], const expireAt, const flags) {
90 |
91 | new name_safe[MAX_NAME_LENGTH * 2]
92 | SQL_QuoteString(Empty_Handle, name_safe, charsmax(name_safe), name)
93 |
94 | new reason_safe[MAX_REASON_LENGTH * 2]
95 | SQL_QuoteString(Empty_Handle, reason_safe, charsmax(reason_safe), reason)
96 |
97 | new adminName_safe[MAX_NAME_LENGTH * 2]
98 | SQL_QuoteString(Empty_Handle, adminName_safe, charsmax(adminName_safe), adminName)
99 |
100 | new query[QUERY_LENGTH]
101 | formatex(query, charsmax(query), "INSERT OR REPLACE INTO %s ", SQL_TBL_GAGS); {
102 | strcat(query, "( name,authid,ip,", charsmax(query))
103 | strcat(query, "reason,admin_name,admin_authid,", charsmax(query))
104 | strcat(query, "admin_ip,created_at,expire_at,flags )", charsmax(query))
105 |
106 | strcat(query, fmt("VALUES ( '%s',", name_safe), charsmax(query))
107 | strcat(query, fmt("'%s',", authID), charsmax(query))
108 | strcat(query, fmt("'%s',", IP), charsmax(query))
109 | strcat(query, fmt("'%s',", reason_safe), charsmax(query))
110 | strcat(query, fmt("'%s',", adminName_safe), charsmax(query))
111 | strcat(query, fmt("'%s',", adminAuthID), charsmax(query))
112 | strcat(query, fmt("'%s',", adminIP), charsmax(query))
113 | strcat(query, fmt("DateTime('now'),"), charsmax(query))
114 | strcat(query, fmt("DateTime(%i, 'unixepoch'),", expireAt), charsmax(query))
115 | strcat(query, fmt("%i ); ", flags), charsmax(query))
116 | }
117 |
118 | strcat(query, "SELECT \
119 | name,authid,ip,reason,\
120 | admin_name,admin_authid,admin_ip,\
121 | strftime('%s',created_at),strftime('%s',expire_at),flags", charsmax(query))
122 | strcat(query, fmt(" FROM %s", SQL_TBL_GAGS), charsmax(query))
123 | strcat(query, fmt(" WHERE authid='%s'", authID), charsmax(query))
124 |
125 | SQL_ThreadQuery(g_tuple, "handle_Saved", query)
126 | }
127 |
128 | public handle_Saved(failstate, Handle: query, error[], errnum, data[], size, Float: queuetime) {
129 | if (IsSQLQueryFailed(failstate, query, error, errnum)) {
130 | return
131 | }
132 |
133 | enum { res_name, res_authid, res_ip, res_reason,
134 | res_admin_name, res_admin_authid, res_admin_ip,
135 | res_created_at, res_expire_at, res_flags
136 | }
137 |
138 | new name[MAX_NAME_LENGTH]; SQL_ReadResult(query, res_name, name, charsmax(name))
139 | new authID[MAX_AUTHID_LENGTH]; SQL_ReadResult(query, res_authid, authID, charsmax(authID))
140 | new IP[MAX_IP_LENGTH]; SQL_ReadResult(query, res_ip, IP, charsmax(IP))
141 | new reason[MAX_REASON_LENGTH]; SQL_ReadResult(query, res_reason, reason, charsmax(reason))
142 |
143 | new adminName[MAX_NAME_LENGTH]; SQL_ReadResult(query, res_admin_name, adminName, charsmax(adminName))
144 | new adminAuthID[MAX_AUTHID_LENGTH]; SQL_ReadResult(query, res_admin_authid, adminAuthID, charsmax(adminAuthID))
145 | new adminIP[MAX_IP_LENGTH]; SQL_ReadResult(query, res_admin_ip, adminIP, charsmax(adminIP))
146 |
147 | new createdAt = SQL_ReadResult(query, res_created_at)
148 | new expireAt = SQL_ReadResult(query, res_expire_at)
149 | new flags = SQL_ReadResult(query, res_flags)
150 |
151 | CA_Log(logLevel_Debug, "Player gag saved {'%s', '%s', '%s', '%s', '%s', '%s', '%s', %i, %i, %i} (queryTime: '%.3f' sec)", \
152 | name, authID, IP, reason, adminName, adminAuthID, adminIP, createdAt, expireAt, flags,\
153 | queuetime \
154 | )
155 |
156 | ExecuteForward(g_fwd_StorageSaved, g_ret,
157 | name, authID, IP, reason,
158 | adminName, adminAuthID, adminIP,
159 | createdAt, expireAt, flags
160 | )
161 | }
162 |
163 | Storage_Load(const authID[]) {
164 | new query[QUERY_LENGTH]
165 | formatex(query, charsmax(query), "SELECT name, authid, ip, reason,\
166 | admin_name, admin_authid, admin_ip, \
167 | strftime('%%s', created_at), strftime('%%s', expire_at), flags FROM %s", SQL_TBL_GAGS); {
168 | strcat(query, fmt(" WHERE (authid = '%s')", authID), charsmax(query))
169 | strcat(query, " AND ( expire_at = DateTime(9999999999, 'unixepoch') OR (expire_at > DateTime('now')) ) LIMIT 1", charsmax(query))
170 | }
171 |
172 | SQL_ThreadQuery(g_tuple, "handle_Loaded", query)
173 | }
174 |
175 | public handle_Loaded(failstate, Handle: query, error[], errnum, data[], size, Float: queuetime) {
176 | if (IsSQLQueryFailed(failstate, query, error, errnum)) {
177 | return
178 | }
179 |
180 | enum { res_name, res_authid, res_ip, res_reason,
181 | res_admin_name, res_admin_authid, res_admin_ip,
182 | res_created_at, res_expire_at, res_flags
183 | }
184 |
185 | new bool: found = (SQL_NumResults(query) != 0)
186 |
187 | if (!found) {
188 | return
189 | }
190 |
191 | new name[MAX_NAME_LENGTH]; SQL_ReadResult(query, res_name, name, charsmax(name))
192 | new authID[MAX_AUTHID_LENGTH]; SQL_ReadResult(query, res_authid, authID, charsmax(authID))
193 | new IP[MAX_IP_LENGTH]; SQL_ReadResult(query, res_ip, IP, charsmax(IP))
194 | new reason[MAX_REASON_LENGTH]; SQL_ReadResult(query, res_reason, reason, charsmax(reason))
195 |
196 | new adminName[MAX_NAME_LENGTH]; SQL_ReadResult(query, res_admin_name, adminName, charsmax(adminName))
197 | new adminAuthID[MAX_AUTHID_LENGTH]; SQL_ReadResult(query, res_admin_authid, adminAuthID, charsmax(adminAuthID))
198 | new adminIP[MAX_IP_LENGTH]; SQL_ReadResult(query, res_admin_ip, adminIP, charsmax(adminIP))
199 |
200 | new createdAt = SQL_ReadResult(query, res_created_at)
201 | new expireAt = SQL_ReadResult(query, res_expire_at)
202 | new flags = SQL_ReadResult(query, res_flags)
203 |
204 | CA_Log(logLevel_Debug, "Player gag loaded {'%s', '%s', '%s', '%s', '%s', '%s', '%s', %i, %i, %i} (queryTime: '%.3f' sec)", \
205 | name, authID, IP, reason, adminName, adminAuthID, adminIP, createdAt, expireAt, flags,\
206 | queuetime \
207 | )
208 |
209 | ExecuteForward(g_fwd_StorageLoaded, g_ret,
210 | name, authID, IP, reason,
211 | adminName, adminAuthID, adminIP,
212 | createdAt, expireAt, flags
213 | )
214 | }
215 |
216 | Storage_Remove(const authID[]) {
217 | new query[QUERY_LENGTH]
218 | formatex(query, charsmax(query), "DELETE FROM %s ", SQL_TBL_GAGS); {
219 | strcat(query, fmt("WHERE (authid = '%s')", authID), charsmax(query))
220 | }
221 |
222 | SQL_ThreadQuery(g_tuple, "handle_Removed", query)
223 | }
224 |
225 | public handle_Removed(failstate, Handle: query, error[], errnum, data[], size, Float: queuetime) {
226 | if (IsSQLQueryFailed(failstate, query, error, errnum)) {
227 | return
228 | }
229 |
230 | CA_Log(logLevel_Debug, "Player gag removed { } (queryTime: '%.3f' sec)", \
231 | queuetime \
232 | )
233 |
234 | ExecuteForward(g_fwd_StorageRemoved, g_ret)
235 | }
236 |
--------------------------------------------------------------------------------
/cstrike/addons/amxmodx/scripting/include/CA_GAG_API.inc:
--------------------------------------------------------------------------------
1 | /** Copyright © 2021 Sergey Shorokhov
2 | *
3 | * Chat Additions: Gag [API] include file.
4 | *
5 | */
6 |
7 | #if defined _CA_GAG_API_included
8 | #endinput
9 | #endif
10 |
11 | #define _CA_GAG_API_included
12 |
13 | enum any: gag_flags_s ( <<=1 ) {
14 | gagFlag_Removed = 0,
15 | gagFlag_Say = 1, // a
16 | gagFlag_SayTeam, // b
17 | gagFlag_Voice // c
18 | }
19 |
20 | const MAX_REASON_LEN = 128
21 | const MAX_WHITELIST_CMD_LEN = 32
22 |
23 | enum reason_s {
24 | r_name[MAX_REASON_LEN],
25 | r_time,
26 | gag_flags_s: r_flags
27 | }
28 |
29 | enum gagData_s {
30 | gd_target,
31 | gd_name[MAX_NAME_LENGTH],
32 | gd_authID[MAX_AUTHID_LENGTH],
33 | gd_IP[MAX_IP_LENGTH],
34 |
35 | gd_admin,
36 | gd_adminName[MAX_NAME_LENGTH],
37 | gd_adminAuthID[MAX_AUTHID_LENGTH],
38 | gd_adminIP[MAX_IP_LENGTH],
39 |
40 | gd_reason[reason_s],
41 | gd_expireAt
42 | }
43 |
44 | stock gag_flags_s: flags_to_bit(const flagsStr[]) {
45 | new gag_flags_s: bits = gagFlag_Removed
46 |
47 | if (containi(flagsStr, "a") != -1) bits |= gagFlag_Say
48 | if (containi(flagsStr, "b") != -1) bits |= gagFlag_SayTeam
49 | if (containi(flagsStr, "c") != -1) bits |= gagFlag_Voice
50 |
51 | return bits
52 | }
53 |
54 | stock bits_to_flags(const gag_flags_s: bits) {
55 | new flagsStr[4]
56 | if (bits & gagFlag_Say) add(flagsStr, charsmax(flagsStr), "a")
57 | if (bits & gagFlag_SayTeam) add(flagsStr, charsmax(flagsStr), "b")
58 | if (bits & gagFlag_Voice) add(flagsStr, charsmax(flagsStr), "c")
59 |
60 | return flagsStr
61 | }
62 |
63 | stock GagData_Reset(gagData[gagData_s]) {
64 | gagData[gd_target] = 0
65 | gagData[gd_name][0] = EOS
66 | gagData[gd_authID][0] = EOS
67 | gagData[gd_IP][0] = EOS
68 |
69 | gagData[gd_admin] = 0
70 | gagData[gd_adminName][0] = EOS
71 | gagData[gd_adminAuthID][0] = EOS
72 | gagData[gd_adminIP][0] = EOS
73 |
74 | gagData[gd_reason][r_name][0] = EOS
75 | gagData[gd_reason][r_time] = 0
76 | gagData[gd_reason][r_flags] = gagFlag_Removed
77 |
78 | gagData[gd_expireAt] = 0
79 | }
80 |
81 | stock GagData_Copy(to[gagData_s], const from[gagData_s]) {
82 | to[gd_target] = from[gd_target]
83 | copy(to[gd_name], charsmax(to[gd_name]), from[gd_name])
84 | copy(to[gd_authID], charsmax(to[gd_authID]), from[gd_authID])
85 | copy(to[gd_IP], charsmax(to[gd_IP]), from[gd_IP])
86 |
87 | to[gd_admin] = from[gd_admin]
88 | copy(to[gd_adminName], charsmax(to[gd_adminName]), from[gd_adminName])
89 | copy(to[gd_adminAuthID], charsmax(to[gd_adminAuthID]), from[gd_adminAuthID])
90 | copy(to[gd_adminIP], charsmax(to[gd_adminIP]), from[gd_adminIP])
91 |
92 | copy(to[gd_reason][r_name], charsmax(to[r_name]), from[gd_reason][r_name])
93 | to[gd_reason][r_time] = from[gd_reason][r_time]
94 | to[gd_reason][r_flags] = from[gd_reason][r_flags]
95 |
96 | to[gd_expireAt] = from[gd_expireAt]
97 | }
98 |
99 | stock bool: GagData_IsEqual(const arr1[gagData_s], const arr2[gagData_s]) {
100 | if (arr1[gd_reason][r_time] != arr2[gd_reason][r_time]) {
101 | return false
102 | }
103 |
104 | if (arr1[gd_reason][r_flags] != arr2[gd_reason][r_flags]) {
105 | return false
106 | }
107 |
108 | if (strcmp(arr1[gd_reason][r_name], arr2[gd_reason][r_name]) != 0) {
109 | return false
110 | }
111 |
112 | return true
113 | }
114 |
115 | stock GagData_GetPersonalData(const admin = 0, const target, buffer[gagData_s]) {
116 | // get's target data
117 | buffer[gd_target] = target
118 | get_user_name(target, buffer[gd_name], charsmax(buffer[gd_name]))
119 | get_user_authid(target, buffer[gd_authID], charsmax(buffer[gd_authID]))
120 | get_user_ip(target, buffer[gd_IP], charsmax(buffer[gd_IP]), .without_port = true)
121 |
122 | // get's admin data
123 | buffer[gd_admin] = admin
124 | get_user_name(admin, buffer[gd_adminName], charsmax(buffer[gd_adminName]))
125 | get_user_authid(admin, buffer[gd_adminAuthID], charsmax(buffer[gd_adminAuthID]))
126 | get_user_ip(admin, buffer[gd_adminIP], charsmax(buffer[gd_adminIP]), .without_port = true)
127 | }
128 |
129 |
130 |
131 |
132 |
133 | /**
134 | * Sets client's gag data.
135 | *
136 | * @param index Client index
137 | * @param reason Reason
138 | * @param Minutes Minutes
139 | * @param Flags Flags
140 | *
141 | * @noreturn
142 | * @error If the client index is not within the range of 1 to
143 | * MaxClients, or the client is not connected, an error
144 | * will be thrown.
145 | */
146 | native bool: ca_set_user_gag(const index, const reason[], const minutes, const gag_flags_s: flags)
147 |
148 | /**
149 | * Get client's gag data.
150 | *
151 | * @param index Client index
152 | * @param reason Gag reason
153 | * @param minutes minutes
154 | * @param flags flags
155 | *
156 | * @return True if has Gag.
157 | * @error If the client index is not within the range of 1 to
158 | * MaxClients, or the client is not connected, an error
159 | * will be thrown.
160 | */
161 | native bool: ca_get_user_gag(const index, reason[], &minutes, &gag_flags_s: flags)
162 |
163 | /**
164 | * Has client gag?
165 | *
166 | * @param index Client index
167 | *
168 | * @return True if has Gag.
169 | * @error If the client index is not within the range of 1 to
170 | * MaxClients, or the client is not connected, an error
171 | * will be thrown.
172 | */
173 | native bool: ca_has_user_gag(const index)
174 |
175 | /**
176 | * Remove client's gag data..
177 | *
178 | * @param target Target Index
179 | * @param admin Admin Index (0 - server)
180 | *
181 | * @return True if gag has been removed.
182 | * @error If the client index is not within the range of 1 to
183 | * MaxClients, or the client is not connected, an error
184 | * will be thrown.
185 | */
186 | native bool: ca_remove_user_gag(const target, admin = 0)
187 |
188 | /**
189 | * Called on Gag save.
190 | *
191 | * @param target Targed index
192 | * @param name Targed name
193 | * @param authID Targed AuthID
194 | * @param IP Targed IP
195 | * @param adminName Admin name
196 | * @param adminAuthID Admin authID
197 | * @param adminIP Admin IP
198 | * @param reason Reason
199 | * @param time Time (in seconds)
200 | * @param flags Flags (chat, teamChat, voice)
201 | * @param expireAt Time when gag expire
202 | *
203 | * @return Return CA_SUPERCEDE for prevent Gag.
204 | */
205 | forward CA_gag_setted(
206 | const target, name[], authID[], IP[],
207 | adminName[], adminAuthID[], adminIP[],
208 | reason[], time, gag_flags_s: flags,
209 | expireAt)
210 |
211 | /**
212 | * Called on gag remove action.
213 | *
214 | * @param target Target index
215 | * @param target Reason
216 | * @param minutes Time (in seconds)
217 | * @param flags Flags (chat, teamChat, voice)
218 | *
219 | * @return Return CA_SUPERCEDE for prevent Gag remove.
220 | */
221 | forward CA_gag_removed(const target, reason[], minutes, gag_flags_s: flags)
222 |
--------------------------------------------------------------------------------
/cstrike/addons/amxmodx/scripting/include/CA_StorageAPI.inc:
--------------------------------------------------------------------------------
1 | #if defined _CA_STORAGE_API_included
2 | #endinput
3 | #endif
4 |
5 | #define _CA_STORAGE_API_included
6 |
7 | /*
8 | *
9 | */
10 | native CA_Storage_Save(const name[], const authID[], const IP[], const reason[], const adminName[], const adminAuthID[], const adminIP[], const expireAt, const flags)
11 |
12 | /*
13 | *
14 | */
15 | native CA_Storage_Load(const authID[])
16 |
17 | /*
18 | *
19 | */
20 | native CA_Storage_Remove(const authID[])
21 |
22 |
23 | /*
24 | *
25 | */
26 | forward CA_Storage_Initialized()
27 |
28 | /*
29 | *
30 | */
31 | forward CA_Storage_Saved(const name[], const authID[], const IP[], const reason[],
32 | const adminName[], const adminAuthID[], const adminIP[],
33 | const createdAt, const expireAt, const flags)
34 |
35 | /*
36 | *
37 | */
38 | forward CA_Storage_Loaded(const name[], const authID[], const IP[], const reason[],
39 | const adminName[], const adminAuthID[], const adminIP[],
40 | const createdAt, const expireAt, const flags)
41 |
42 | /*
43 | *
44 | */
45 | forward CA_Storage_Removed()
46 |
--------------------------------------------------------------------------------
/cstrike/addons/amxmodx/scripting/include/CA_StorageAPI_endpoint.inc:
--------------------------------------------------------------------------------
1 | #if defined _CA_STORAGE_API_ENDPOINT_included
2 | #endinput
3 | #endif
4 |
5 | #define _CA_STORAGE_API_ENDPOINT_included
6 |
7 | #pragma dynamic 131072
8 |
9 | new bool: g_storageInitialized
10 |
11 | stock bool: IsSQLQueryFailed(const failstate, const Handle: query, const error[], const errNum) {
12 | switch (failstate) {
13 | case TQUERY_CONNECT_FAILED: {
14 | log_amx("SQL: connection failed [%i] `%s`", errNum, error)
15 | return true
16 | }
17 | case TQUERY_QUERY_FAILED: {
18 | log_amx("SQL: query failed [%i] %s", errNum, error)
19 |
20 | server_print("^n^n ===> Query:")
21 | new buffer[8192]; SQL_GetQueryString(query, buffer, charsmax(buffer))
22 | for(new i, len = strlen(buffer); i < len; i+=255) {
23 | server_print(fmt("%-255s", buffer[i]))
24 | }
25 |
26 | return true
27 | }
28 | }
29 |
30 | return false
31 | }
32 |
33 | // Should be realized in each storage
34 | RegisterNatives() {
35 | register_native("CA_Storage_Save", "native_Storage_Save")
36 | register_native("CA_Storage_Load", "native_Storage_Load")
37 | register_native("CA_Storage_Remove", "native_Storage_Remove")
38 | register_native("CA_Storage_IsInitialized", "native_Storage_IsInitialized")
39 | }
40 | public native_Storage_Save(const plugin_id, const argc) {
41 | enum { arg_name = 1, arg_authID, arg_IP, arg_reason, arg_adminName, arg_adminAuthID, arg_adminIP, arg_expireAt, arg_flags }
42 |
43 | new name[MAX_NAME_LENGTH]; get_string(arg_name, name, charsmax(name))
44 | new authID[MAX_AUTHID_LENGTH]; get_string(arg_authID, authID, charsmax(authID))
45 | new IP[MAX_IP_LENGTH]; get_string(arg_IP, IP, charsmax(IP))
46 | new reason[256]; get_string(arg_reason, reason, charsmax(reason))
47 | new adminName[MAX_NAME_LENGTH]; get_string(arg_adminName, adminName, charsmax(adminName))
48 | new adminAuthID[MAX_AUTHID_LENGTH]; get_string(arg_adminAuthID, adminAuthID, charsmax(adminAuthID))
49 | new adminIP[MAX_IP_LENGTH]; get_string(arg_adminIP, adminIP, charsmax(adminIP))
50 | new expireAt = get_param(arg_expireAt)
51 | new flags = get_param(arg_flags)
52 |
53 | Storage_Save(name, authID, IP, reason, adminName, adminAuthID, adminIP, expireAt, flags)
54 | }
55 | public native_Storage_Load(const plugin_id, const argc) {
56 | enum { arg_authID = 1 }
57 |
58 | new authID[MAX_AUTHID_LENGTH]; get_string(arg_authID, authID, charsmax(authID))
59 | Storage_Load(authID)
60 | }
61 | public native_Storage_Remove(const plugin_id, const argc) {
62 | enum { arg_authID = 1 }
63 |
64 | new authID[MAX_AUTHID_LENGTH]; get_string(arg_authID, authID, charsmax(authID))
65 | Storage_Remove(authID)
66 | }
67 | public bool: native_Storage_IsInitialized(const plugin_id, const argc) {
68 | return g_storageInitialized
69 | }
70 |
71 |
72 | // Forwards handlers
73 | new g_fwd_StorageInitialized = INVALID_HANDLE
74 | new g_fwd_StorageSaved = INVALID_HANDLE
75 | new g_fwd_StorageLoaded = INVALID_HANDLE
76 | new g_fwd_StorageRemoved = INVALID_HANDLE
77 | new g_ret
78 | // Should be realized in each storage
79 | RegisterForwards() {
80 | g_fwd_StorageInitialized = CreateMultiForward("CA_Storage_Initialized", ET_IGNORE)
81 | g_fwd_StorageSaved = CreateMultiForward("CA_Storage_Saved", ET_IGNORE,
82 | FP_STRING, FP_STRING, FP_STRING, FP_STRING,
83 | FP_STRING, FP_STRING, FP_STRING,
84 | FP_CELL, FP_CELL, FP_CELL
85 | )
86 | g_fwd_StorageLoaded = CreateMultiForward("CA_Storage_Loaded", ET_IGNORE,
87 | FP_STRING, FP_STRING, FP_STRING, FP_STRING,
88 | FP_STRING, FP_STRING, FP_STRING,
89 | FP_CELL, FP_CELL, FP_CELL
90 | )
91 | g_fwd_StorageRemoved = CreateMultiForward("CA_Storage_Removed", ET_IGNORE)
92 | }
93 |
94 |
95 |
96 | /* TEST
97 |
98 | public CA_Storage_Initialized() {
99 | new name[] = "Some safe name"
100 | new authID[] = "0:1:2345678"
101 | new IP[] = "123.123.123.123"
102 | new reason[] = "Some safe reason"
103 | new adminName[] = "Some safe admin name"
104 | new adminAuthID[] = "Some safe admin authID"
105 | new adminIP[] = "Some safe admin IP"
106 | new expireAt = 1624232019
107 | new flags = 3
108 |
109 | CA_Storage_Save(name, authID, IP, reason, adminName, adminAuthID, adminIP, expireAt, flags)
110 | }
111 | public CA_Storage_Saved() {
112 | new authID[] = "0:1:2345678"
113 | CA_Storage_Load(authID)
114 | }
115 | public CA_Storage_Loaded(const name[], const authID[], const IP[], const reason[],
116 | const adminName[], const adminAuthID[], const adminIP[],
117 | const createdAt, const expireAt, const flags) {
118 | log_amx(" > CA_Storage_Loaded{`%s`,`%s`,%s`,`%s`,`%s`,`%s`,`%s`,%i,%i,%i}",
119 | name, authID, reason, IP,
120 | adminName, adminAuthID, adminIP,
121 | createdAt, expireAt, flags)
122 | CA_Storage_Remove(authID)
123 | }
124 | public CA_Storage_Removed() {
125 |
126 | }
127 | */
128 |
--------------------------------------------------------------------------------
/cstrike/addons/amxmodx/scripting/include/ChatAdditions.inc:
--------------------------------------------------------------------------------
1 | /** Copyright © 2020 Sergey Shorokhov
2 | *
3 | * Chat Additions API include file.
4 | *
5 | */
6 |
7 | #if defined _CA_API_included
8 | #endinput
9 | #endif
10 |
11 | #define _CA_API_included
12 |
13 | #pragma reqlib ChatAdditions_Core
14 | #if !defined AMXMODX_NOAUTOLOAD
15 | #pragma loadlib ChatAdditions_Core
16 | #endif
17 |
18 | #if !defined CA_VERSION
19 | #define CA_VERSION "%CA_VERSION%"
20 | #endif
21 |
22 | const CA_MAX_MESSAGE_SIZE = 188
23 |
24 | /**
25 | * Return types
26 | */
27 | enum
28 | {
29 | CA_CONTINUE = 0, // Plugin didn't take any action
30 | CA_SUPERCEDE // Skip real function, use my return value
31 | }
32 |
33 | #define CHECK_NATIVE_ARGS_NUM(%1,%2,%3) \
34 | if (%1 < %2) { \
35 | log_error(AMX_ERR_NATIVE, "Invalid num of arguments %d. Expected %d", %1, %2); \
36 | return %3; \
37 | }
38 |
39 | #define CHECK_NATIVE_PLAYER(%1,%2) \
40 | if (!is_user_connected(%1)) { \
41 | log_error(AMX_ERR_NATIVE, "Invalid player %d", %1); \
42 | return %2; \
43 | }
44 |
45 |
46 | enum logLevel_s {
47 | logLevel_Off = 0,
48 | logLevel_Info = 1,
49 | logLevel_Warning,
50 | logLevel_Debug
51 | }
52 |
53 | #define register_trigger_clcmd(%0,%1) \
54 | for (new iter = 0; iter < sizeof(BASE_CHAT_TRIGGERS); iter++) \
55 | { \
56 | register_clcmd(fmt("%s%s", BASE_CHAT_TRIGGERS[iter], %0), %1); \
57 | register_clcmd(fmt("say %s%s", BASE_CHAT_TRIGGERS[iter], %0), %1); \
58 | register_clcmd(fmt("say_team %s%s", BASE_CHAT_TRIGGERS[iter], %0), %1); \
59 | }
60 |
61 | new stock const BASE_CHAT_TRIGGERS[][] = { /* "", */"/", "\", "!", "." }
62 |
63 |
64 | stock parseTime(const value[]) {
65 | const _SECONDS_IN_MINUTE = 60
66 | const _SECONDS_IN_HOUR = 3600
67 | const _SECONDS_IN_DAY = 86400
68 | const _SECONDS_IN_WEEK = 604800
69 | const _SECONDS_IN_MONTH = 2592000
70 | const _SECONDS_IN_YEAR = 31536000
71 |
72 | new t, k
73 | for (new i; value[i] != EOS; i++) {
74 | switch (value[i]) {
75 | case '0'..'9': {
76 | t = (t * 10) + (value[i] - '0')
77 | }
78 |
79 | case 'i': {
80 | k += t * _SECONDS_IN_MINUTE
81 | t = 0
82 | }
83 |
84 | case 'h': {
85 | k += t * _SECONDS_IN_HOUR
86 | t = 0
87 | }
88 |
89 | case 'd': {
90 | k += t * _SECONDS_IN_DAY
91 | t = 0
92 | }
93 |
94 | case 'w': {
95 | k += t * _SECONDS_IN_WEEK
96 | t = 0
97 | }
98 |
99 | case 'm': {
100 | k += t * _SECONDS_IN_MONTH
101 | t = 0
102 | }
103 |
104 | case 'y': {
105 | k += t * _SECONDS_IN_YEAR
106 | t = 0
107 | }
108 |
109 | default: {
110 | break
111 | }
112 | }
113 | }
114 |
115 | return k + t
116 | }
117 |
118 | stock show_activity_ex(const actorId, const actorName[], const message[], any: ...) {
119 | enum { arg_format = 4 }
120 |
121 | static _amx_show_activity
122 | if (!_amx_show_activity) {
123 | _amx_show_activity = get_cvar_pointer("amx_show_activity")
124 | if (!_amx_show_activity) {
125 | _amx_show_activity = create_cvar("amx_show_activity", "2")
126 | }
127 | }
128 |
129 | new prefix[] = "PLAYER"
130 | if (is_user_admin(actorId)) {
131 | copy(prefix, charsmax(prefix), "ADMIN")
132 | }
133 |
134 | static buffer[512]
135 | for(new i = 1; i <= MaxClients; i++) {
136 | if (!is_user_connected(i) && !is_user_bot(i)) {
137 | continue
138 | }
139 |
140 | new bool: isAdmin = bool: is_user_admin(i)
141 | SetGlobalTransTarget(i)
142 | vformat(buffer, charsmax(buffer), message, arg_format)
143 |
144 | switch (get_pcvar_num(_amx_show_activity)) {
145 | case 1: { // Hide name for all
146 | client_print_color(i, i, "%L %s", i, prefix, buffer)
147 | }
148 | case 2: { // Show name to all
149 | client_print_color(i, i, "%L %s: %s", i, prefix, actorName, buffer)
150 | }
151 | case 3: { // show name only to admins, hide name from normal users
152 | client_print_color(i, i, "%L %s: %s", i, prefix, isAdmin ? actorName : "", buffer)
153 | }
154 | case 4: { // show name only to admins, show nothing to normal users
155 | if (isAdmin) {
156 | client_print_color(i, i, "%L %s: %s", i, prefix, actorName, buffer)
157 | }
158 | }
159 | case 5: { // show only to admins without actor name
160 | if (isAdmin) {
161 | client_print_color(i, i, "%L: %s", i, prefix, buffer)
162 | }
163 | }
164 | }
165 | }
166 | }
167 |
168 | stock FindPlayerByTarget(const buffer[]) {
169 | if (buffer[0] == '#' && buffer[1]) {
170 | return find_player_ex(FindPlayer_MatchUserId, strtol(buffer[1]))
171 | }
172 |
173 | new result = find_player_ex(FindPlayer_MatchAuthId, buffer)
174 | if (!result) {
175 | result = find_player_ex(FindPlayer_MatchIP, buffer)
176 | }
177 |
178 | if (!result) {
179 | result = find_player_ex(FindPlayer_MatchNameSubstring | FindPlayer_CaseInsensitive | FindPlayer_LastMatched, buffer)
180 | }
181 |
182 | return result
183 | }
184 |
185 | stock UTIL_SendAudio(const id, const sample[]) {
186 | if (sample[0] == EOS) {
187 | return
188 | }
189 |
190 | static msgId_SendAudio
191 | if (!msgId_SendAudio) {
192 | msgId_SendAudio = get_user_msgid("SendAudio")
193 | }
194 |
195 | message_begin(MSG_ONE_UNRELIABLE, msgId_SendAudio, .player = id)
196 | write_byte(id)
197 | write_string(sample)
198 | write_short(PITCH_NORM)
199 | message_end()
200 | }
201 |
202 | stock UTIL_BarTime(const id, const time) {
203 | static msgId_BarTime
204 | if (!msgId_BarTime) {
205 | msgId_BarTime = get_user_msgid("BarTime")
206 | }
207 |
208 | message_begin(MSG_ONE_UNRELIABLE, msgId_BarTime, .player = id)
209 | write_short(time)
210 | message_end()
211 | }
212 |
213 |
214 | /**
215 | * Log a message for every ChatAdditions module.
216 | *
217 | * @param level Log level, see logLevel_* destination constants in ChatAdditions.inc
218 | * @param message Formatting rules.
219 | * @param ... Variable number of formatting parameters
220 | *
221 | * @return True if a message logged, false otherwise.
222 | */
223 |
224 | native bool: CA_Log(logLevel_s: level, const message[], any:...)
225 |
226 | /**
227 | * Called to determine if the Receiver has muted (blocked) the Sender.
228 | * NOTE: Setting from client menu (Players list -> Mute)
229 | *
230 | * @param receiver Receiver client id.
231 | * @param sender Sender client id.
232 | *
233 | * @return Returns true if the receiver has blocked the sender
234 | */
235 |
236 | native bool: CA_PlayerHasBlockedPlayer(const receiver, const sender)
237 |
238 | /**
239 | * Called when player say to chat.
240 | *
241 | * @param index Client index.
242 | * @param isTeamMessage Is team message (say_team).
243 | * @param message Client message.
244 | *
245 | * @return CA_CONTINUE to allow send message
246 | * CA_SUPERCEDE or higher to prevent message
247 | */
248 | forward CA_Client_Say(index, const bool: isTeamMessage, const message[])
249 |
250 |
251 | /**
252 | * Called when player begins to speak.
253 | *
254 | * @note
255 | *
256 | * @param listener Receiver index.
257 | * @param sender Sender index.
258 | *
259 | * @return CA_CONTINUE to allow send voice
260 | * CA_SUPERCEDE or higher to prevent the voice
261 | */
262 | forward CA_Client_Voice(const listener, const sender)
263 |
264 |
265 | /**
266 | * Called when player change nickname.
267 | *
268 | * @note
269 | *
270 | * @param id Client index.
271 | * @param newName New name.
272 | *
273 | * @return CA_CONTINUE to allow change nickname
274 | * CA_SUPERCEDE or higher to prevent
275 | */
276 | forward CA_Client_ChangeName(const id, const newName[])
277 |
--------------------------------------------------------------------------------
/cstrike/addons/amxmodx/scripting/include/cellqueue.inc:
--------------------------------------------------------------------------------
1 | #include "cellarray.inc"
2 |
3 | enum Queue {
4 | Invalid_Queue = 0
5 | }
6 |
7 | stock Queue: QueueCreate(const cellsize = 1) {
8 | return Queue: ArrayCreate(cellsize)
9 | }
10 |
11 | stock QueueDestroy(&Queue: which) {
12 | return ArrayDestroy(Array: which)
13 | }
14 |
15 | stock QueueClear(const &Queue: which) {
16 | ArrayClear(Array: which)
17 | }
18 |
19 | stock Queue: QueueClone(const &Queue: which) {
20 | return ArrayClone(Array: which)
21 | }
22 |
23 | stock QueuePushCell(const &Queue: which, const any: value) {
24 | return ArrayPushCell(Array: which, any: value)
25 | }
26 |
27 | stock QueuePushString(const &Queue: which, const value[]) {
28 | return ArrayPushString(Array: which, value)
29 | }
30 |
31 | stock QueuePushArray(const &Queue: which, const any: value[], const size = -1) {
32 | return ArrayPushArray(Array: which, value, size)
33 | }
34 |
35 | stock any: QueuePopCell(const &Queue: which) {
36 | new any: value = ArrayGetCell(Array: which, 0)
37 | ArrayDeleteItem(Array: which, 0)
38 | return value
39 | }
40 |
41 | stock QueuePopString(const &Queue: which, buffer[], const maxlength) {
42 | new charCount = ArrayGetString(Array: which, 0, buffer, maxlength)
43 | ArrayDeleteItem(Array: which, 0)
44 | return charCount
45 | }
46 |
47 | stock QueuePopArray(const &Queue: which, buffer[], const size) {
48 | new cellCount = ArrayGetArray(Array: which, 0, buffer, size)
49 | ArrayDeleteItem(Array: which, 0)
50 | return cellCount
51 | }
52 |
53 | stock any: QueueFrontCell(const &Queue: which) {
54 | new any: value = ArrayGetCell(Array: which, 0)
55 | return value
56 | }
57 |
58 | stock QueueFrontString(const &Queue: which, buffer[], const maxlength) {
59 | new charCount = ArrayGetString(Array: which, 0, buffer, maxlength)
60 | return charCount
61 | }
62 |
63 | stock QueueFrontArray(const &Queue: which, buffer[], const size) {
64 | new cellCount = ArrayGetArray(Array: which, 0, buffer, size)
65 | return cellCount
66 | }
67 |
68 | stock any: QueueRearCell(const &Queue: which) {
69 | new any: value = ArrayGetCell(Array: which, QueueSize(which) - 1)
70 | return value
71 | }
72 |
73 | stock QueueRearString(const &Queue: which, buffer[], const maxlength) {
74 | new charCount = ArrayGetString(Array: which, QueueSize(which) - 1, buffer, maxlength)
75 | return charCount
76 | }
77 |
78 | stock QueueRearArray(const &Queue: which, buffer[], const size) {
79 | new cellCount = ArrayGetArray(Array: which, QueueSize(which) - 1, buffer, size)
80 | return cellCount
81 | }
82 |
83 | stock QueueSize(const &Queue: which) {
84 | return ArraySize(Array: which)
85 | }
86 |
--------------------------------------------------------------------------------