pymodcs 0.17.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pymod/__init__.py +740 -0
- pymod/__init__.pyi +1413 -0
- pymod/__main__.py +78 -0
- pymod/_access.py +555 -0
- pymod/_assets.py +173 -0
- pymod/_audio.py +127 -0
- pymod/_chat.py +116 -0
- pymod/_color.py +191 -0
- pymod/_config.py +309 -0
- pymod/_cs.py +445 -0
- pymod/_cs_batch.py +149 -0
- pymod/_cs_specs.py +1 -0
- pymod/_cs_types.py +235 -0
- pymod/_cvars.py +256 -0
- pymod/_database.py +132 -0
- pymod/_diagnostics.py +53 -0
- pymod/_easy.py +75 -0
- pymod/_effects.py +427 -0
- pymod/_entities.py +888 -0
- pymod/_events.py +70 -0
- pymod/_geometry.py +543 -0
- pymod/_hook_api.py +268 -0
- pymod/_hooks.py +205 -0
- pymod/_http_files.py +293 -0
- pymod/_hud.py +212 -0
- pymod/_i18n.py +164 -0
- pymod/_menus.py +128 -0
- pymod/_messages.py +220 -0
- pymod/_movement.py +396 -0
- pymod/_player.py +605 -0
- pymod/_plugin.py +735 -0
- pymod/_plugin.pyi +4540 -0
- pymod/_plugins.py +241 -0
- pymod/_position.py +66 -0
- pymod/_position.pyi +44 -0
- pymod/_resources.py +196 -0
- pymod/_runtime.py +8 -0
- pymod/_schema.py +259 -0
- pymod/_sdk_native.py +22 -0
- pymod/_services.py +820 -0
- pymod/_simple_db.py +408 -0
- pymod/_timing.py +208 -0
- pymod/_voice.py +118 -0
- pymod/_web.py +697 -0
- pymod/docs/async.md +49 -0
- pymod/docs/compatibility.md +41 -0
- pymod/docs/configuration.md +101 -0
- pymod/docs/geometry.md +62 -0
- pymod/docs/hook-add_account.md +45 -0
- pymod/docs/hook-add_multi_damage.md +48 -0
- pymod/docs/hook-add_player_item.md +44 -0
- pymod/docs/hook-add_points.md +44 -0
- pymod/docs/hook-add_points_to_team.md +44 -0
- pymod/docs/hook-apply_multi_damage.md +46 -0
- pymod/docs/hook-balance_teams.md +42 -0
- pymod/docs/hook-blind.md +46 -0
- pymod/docs/hook-bomb_defuse_end.md +45 -0
- pymod/docs/hook-bomb_defuse_start.md +44 -0
- pymod/docs/hook-bomb_explode.md +44 -0
- pymod/docs/hook-bot_event.md +47 -0
- pymod/docs/hook-buy_gun_ammo.md +45 -0
- pymod/docs/hook-buy_item.md +43 -0
- pymod/docs/hook-buy_weapon.md +43 -0
- pymod/docs/hook-can_have_player_item.md +44 -0
- pymod/docs/hook-can_hear_player.md +44 -0
- pymod/docs/hook-can_respawn.md +42 -0
- pymod/docs/hook-can_switch_team.md +43 -0
- pymod/docs/hook-can_take_damage.md +44 -0
- pymod/docs/hook-change_level.md +42 -0
- pymod/docs/hook-check_map_conditions.md +42 -0
- pymod/docs/hook-check_time_damage.md +42 -0
- pymod/docs/hook-check_win_conditions.md +42 -0
- pymod/docs/hook-choose_appearance.md +43 -0
- pymod/docs/hook-choose_team.md +43 -0
- pymod/docs/hook-classify.md +42 -0
- pymod/docs/hook-cleanup_map.md +42 -0
- pymod/docs/hook-clear_multi_damage.md +42 -0
- pymod/docs/hook-client_userinfo_changed.md +43 -0
- pymod/docs/hook-create_weaponbox.md +52 -0
- pymod/docs/hook-cs_postthink.md +42 -0
- pymod/docs/hook-cs_prethink.md +42 -0
- pymod/docs/hook-damage.md +48 -0
- pymod/docs/hook-damage_impulse.md +46 -0
- pymod/docs/hook-dead_player_weapons.md +42 -0
- pymod/docs/hook-death_notice.md +46 -0
- pymod/docs/hook-death_sound.md +42 -0
- pymod/docs/hook-disappear.md +42 -0
- pymod/docs/hook-drop_idle_player.md +43 -0
- pymod/docs/hook-drop_player_item.md +43 -0
- pymod/docs/hook-drop_shield.md +43 -0
- pymod/docs/hook-duck.md +42 -0
- pymod/docs/hook-fall_damage.md +42 -0
- pymod/docs/hook-fire_buckshots.md +51 -0
- pymod/docs/hook-fire_bullets.md +52 -0
- pymod/docs/hook-fire_bullets3.md +54 -0
- pymod/docs/hook-flash_explode.md +44 -0
- pymod/docs/hook-force_camera.md +42 -0
- pymod/docs/hook-free_game_rules.md +43 -0
- pymod/docs/hook-get_into_game.md +42 -0
- pymod/docs/hook-gib_land.md +42 -0
- pymod/docs/hook-gib_spawn.md +43 -0
- pymod/docs/hook-gib_touch.md +44 -0
- pymod/docs/hook-give_ammo.md +45 -0
- pymod/docs/hook-give_c4.md +42 -0
- pymod/docs/hook-give_default_items.md +42 -0
- pymod/docs/hook-give_named_item.md +43 -0
- pymod/docs/hook-give_shield.md +43 -0
- pymod/docs/hook-go_intermission.md +42 -0
- pymod/docs/hook-has_restrict_item.md +44 -0
- pymod/docs/hook-he_explode.md +44 -0
- pymod/docs/hook-hint_message.md +46 -0
- pymod/docs/hook-impulse_commands.md +42 -0
- pymod/docs/hook-install_game_rules.md +42 -0
- pymod/docs/hook-internal_command.md +46 -0
- pymod/docs/hook-is_penetrable.md +48 -0
- pymod/docs/hook-joining_think.md +42 -0
- pymod/docs/hook-jump.md +42 -0
- pymod/docs/hook-killed.md +46 -0
- pymod/docs/hook-make_bomber.md +42 -0
- pymod/docs/hook-make_vip.md +42 -0
- pymod/docs/hook-next_best_weapon.md +44 -0
- pymod/docs/hook-object_caps.md +42 -0
- pymod/docs/hook-observer_find_next.md +44 -0
- pymod/docs/hook-observer_set_mode.md +43 -0
- pymod/docs/hook-observer_think.md +42 -0
- pymod/docs/hook-observer_valid_target.md +44 -0
- pymod/docs/hook-on_spawn_equip.md +44 -0
- pymod/docs/hook-pain.md +44 -0
- pymod/docs/hook-plant_bomb.md +46 -0
- pymod/docs/hook-player_blind.md +50 -0
- pymod/docs/hook-player_death_think.md +42 -0
- pymod/docs/hook-player_got_weapon.md +44 -0
- pymod/docs/hook-player_precache.md +42 -0
- pymod/docs/hook-pm_air_accelerate.md +45 -0
- pymod/docs/hook-pm_air_move.md +43 -0
- pymod/docs/hook-pm_check_water_jump.md +42 -0
- pymod/docs/hook-pm_duck.md +42 -0
- pymod/docs/hook-pm_init.md +43 -0
- pymod/docs/hook-pm_jump.md +42 -0
- pymod/docs/hook-pm_ladder_move.md +43 -0
- pymod/docs/hook-pm_move.md +44 -0
- pymod/docs/hook-pm_play_step_sound.md +44 -0
- pymod/docs/hook-pm_unduck.md +42 -0
- pymod/docs/hook-pm_update_step_sound.md +42 -0
- pymod/docs/hook-pm_water_jump.md +42 -0
- pymod/docs/hook-radio.md +46 -0
- pymod/docs/hook-radius_flash_trace.md +49 -0
- pymod/docs/hook-remove_all_items.md +43 -0
- pymod/docs/hook-remove_guns.md +42 -0
- pymod/docs/hook-remove_player_item.md +44 -0
- pymod/docs/hook-remove_spawn_protection.md +42 -0
- pymod/docs/hook-reset_max_speed.md +42 -0
- pymod/docs/hook-reset_sequence_info.md +42 -0
- pymod/docs/hook-restart_round.md +42 -0
- pymod/docs/hook-round_end.md +45 -0
- pymod/docs/hook-round_freeze_end.md +42 -0
- pymod/docs/hook-round_respawn.md +42 -0
- pymod/docs/hook-rules_player_killed.md +46 -0
- pymod/docs/hook-rules_player_spawn.md +42 -0
- pymod/docs/hook-rules_server_deactivate.md +42 -0
- pymod/docs/hook-rules_spawn_spot.md +42 -0
- pymod/docs/hook-rules_think.md +42 -0
- pymod/docs/hook-select_spawn_point.md +42 -0
- pymod/docs/hook-send_death_message.md +53 -0
- pymod/docs/hook-send_say_message.md +50 -0
- pymod/docs/hook-set_animation.md +43 -0
- pymod/docs/hook-set_spawn_protection.md +43 -0
- pymod/docs/hook-set_userinfo_model.md +44 -0
- pymod/docs/hook-set_userinfo_name.md +44 -0
- pymod/docs/hook-should_switch_weapon.md +44 -0
- pymod/docs/hook-show_menu.md +46 -0
- pymod/docs/hook-show_vgui_menu.md +45 -0
- pymod/docs/hook-smoke_explode.md +42 -0
- pymod/docs/hook-spawn.md +47 -0
- pymod/docs/hook-spawn_head_gib.md +44 -0
- pymod/docs/hook-spawn_random_gibs.md +46 -0
- pymod/docs/hook-start_death_cam.md +42 -0
- pymod/docs/hook-start_observer.md +44 -0
- pymod/docs/hook-switch_team.md +42 -0
- pymod/docs/hook-take_health.md +44 -0
- pymod/docs/hook-team_full.md +43 -0
- pymod/docs/hook-team_stacked.md +44 -0
- pymod/docs/hook-throw_flashbang.md +47 -0
- pymod/docs/hook-throw_grenade.md +48 -0
- pymod/docs/hook-throw_he_grenade.md +49 -0
- pymod/docs/hook-throw_smoke_grenade.md +48 -0
- pymod/docs/hook-trace_attack.md +48 -0
- pymod/docs/hook-update_client_data.md +42 -0
- pymod/docs/hook-update_status_bar.md +42 -0
- pymod/docs/hook-use_empty.md +42 -0
- pymod/docs/hook-weapon_animation.md +44 -0
- pymod/docs/hook-weapon_can_deploy.md +42 -0
- pymod/docs/hook-weapon_deploy.md +47 -0
- pymod/docs/hook-weapon_kickback.md +49 -0
- pymod/docs/hook-weapon_post_frame.md +42 -0
- pymod/docs/hook-weapon_reload.md +45 -0
- pymod/docs/hook-weapon_shotgun_reload.md +48 -0
- pymod/docs/hook-weaponbox_set_model.md +43 -0
- pymod/docs/hooks.md +202 -0
- pymod/docs/hud.md +56 -0
- pymod/docs/index.md +45 -0
- pymod/docs/installation.md +76 -0
- pymod/docs/methods.md +1065 -0
- pymod/docs/packages.md +129 -0
- pymod/docs/permissions.md +61 -0
- pymod/docs/publishing.md +29 -0
- pymod/docs/pycharm.md +116 -0
- pymod/docs/remote.md +120 -0
- pymod/docs/resources.md +63 -0
- pymod/docs/sdk.md +81 -0
- pymod/docs/sqlite.md +86 -0
- pymod/docs/stock.md +38 -0
- pymod/docs/syntax.md +113 -0
- pymod/docs/tested.md +43 -0
- pymod/docs/web.md +82 -0
- pymod/examples/async_io.py +11 -0
- pymod/examples/custom_events.py +12 -0
- pymod/examples/damage_guard.py +11 -0
- pymod/examples/healing_cooldown.py +20 -0
- pymod/examples/hello_world.py +9 -0
- pymod/examples/panel_extension.py +8 -0
- pymod/examples/player_hud.py +11 -0
- pymod/examples/resources_demo.py +11 -0
- pymod/examples/simple_config.py +16 -0
- pymod/examples/sqlite_counter.py +13 -0
- pymod/examples/training_zone.py +16 -0
- pymod/examples/web_profile.py +18 -0
- pymod/hook_events.py +9 -0
- pymod/hook_events.pyi +3376 -0
- pymod/preferences.py +214 -0
- pymod/py.typed +0 -0
- pymod/web.css +19 -0
- pymod/web.js +64 -0
- pymod/web.py +316 -0
- pymodcs-0.17.1.dist-info/METADATA +104 -0
- pymodcs-0.17.1.dist-info/RECORD +241 -0
- pymodcs-0.17.1.dist-info/WHEEL +5 -0
- pymodcs-0.17.1.dist-info/entry_points.txt +2 -0
- pymodcs-0.17.1.dist-info/licenses/LICENSE +340 -0
- pymodcs-0.17.1.dist-info/licenses/LINKING_EXCEPTION.txt +10 -0
- pymodcs-0.17.1.dist-info/top_level.txt +1 -0
pymod/__init__.py
ADDED
|
@@ -0,0 +1,740 @@
|
|
|
1
|
+
"""PyMod: class plugins, named events and optional ReGameDLL hooks for GoldSrc."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
import asyncio
|
|
4
|
+
import inspect
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
import math
|
|
7
|
+
import urllib.request
|
|
8
|
+
from ._sdk_native import native as _native, require_server, ServerRequiredError
|
|
9
|
+
__version__ = '0.17.1'
|
|
10
|
+
|
|
11
|
+
def _manager():
|
|
12
|
+
return require_server()
|
|
13
|
+
|
|
14
|
+
def log(message):
|
|
15
|
+
"""RU:
|
|
16
|
+
Печатает сообщение в серверный журнал с контекстом плагина.
|
|
17
|
+
Параметры: message.
|
|
18
|
+
|
|
19
|
+
EN:
|
|
20
|
+
Writes a message to the server log in the plugin's context.
|
|
21
|
+
Parameters: message."""
|
|
22
|
+
_manager()
|
|
23
|
+
_native.log(str(message))
|
|
24
|
+
from ._movement import PlayerMovement, Vector, Movement, Buttons, PlayerFlags, MoveType
|
|
25
|
+
from ._color import Color
|
|
26
|
+
from ._position import Position
|
|
27
|
+
from ._player import PlayerActions, WeaponId, WeaponState, AmmoState, Rendering
|
|
28
|
+
from ._geometry import PlayerStateHelpers, Team, Box, Zone
|
|
29
|
+
|
|
30
|
+
class Player(PlayerMovement, PlayerActions, PlayerStateHelpers):
|
|
31
|
+
"""RU:
|
|
32
|
+
Игрок и конкретное подключение. Сохранённый объект не начнёт управлять другим игроком при повторном использовании слота.
|
|
33
|
+
Примечания реализации / Implementation notes:
|
|
34
|
+
A connection handle, not a reusable player slot. Safe to retain over await.
|
|
35
|
+
|
|
36
|
+
EN:
|
|
37
|
+
A player connection handle. A retained object never targets a different connection reusing the same slot.
|
|
38
|
+
Implementation notes / Примечания реализации:
|
|
39
|
+
A connection handle, not a reusable player slot. Safe to retain over await."""
|
|
40
|
+
__slots__ = ('_index', '_token')
|
|
41
|
+
|
|
42
|
+
def __init__(self, index, token):
|
|
43
|
+
self._index = index
|
|
44
|
+
self._token = token
|
|
45
|
+
|
|
46
|
+
def __eq__(self, other):
|
|
47
|
+
if not isinstance(other, Player):
|
|
48
|
+
return NotImplemented
|
|
49
|
+
return (self.index, self.token) == (other.index, other.token)
|
|
50
|
+
|
|
51
|
+
def __hash__(self):
|
|
52
|
+
return hash((self.index, self.token))
|
|
53
|
+
|
|
54
|
+
@property
|
|
55
|
+
def index(self):
|
|
56
|
+
"""RU:
|
|
57
|
+
Номер игрового слота.
|
|
58
|
+
|
|
59
|
+
EN:
|
|
60
|
+
Engine slot index."""
|
|
61
|
+
return self._index
|
|
62
|
+
|
|
63
|
+
@property
|
|
64
|
+
def token(self):
|
|
65
|
+
"""RU:
|
|
66
|
+
Идентификатор конкретного подключения.
|
|
67
|
+
|
|
68
|
+
EN:
|
|
69
|
+
Token identifying this exact connection."""
|
|
70
|
+
return self._token
|
|
71
|
+
|
|
72
|
+
@property
|
|
73
|
+
def entity(self):
|
|
74
|
+
"""RU:
|
|
75
|
+
Игровой объект игрока.
|
|
76
|
+
|
|
77
|
+
EN:
|
|
78
|
+
The player's game entity."""
|
|
79
|
+
if not self.connected:
|
|
80
|
+
raise RuntimeError('Player disconnected or belongs to a previous map')
|
|
81
|
+
result = entities.get(self.index)
|
|
82
|
+
if result is None or result.key[3] != self.token:
|
|
83
|
+
raise RuntimeError('Player entity is no longer valid')
|
|
84
|
+
return result
|
|
85
|
+
|
|
86
|
+
@property
|
|
87
|
+
def connected(self):
|
|
88
|
+
"""RU:
|
|
89
|
+
Подключён ли ещё именно этот игрок.
|
|
90
|
+
|
|
91
|
+
EN:
|
|
92
|
+
Whether this exact player connection is still active."""
|
|
93
|
+
_manager()
|
|
94
|
+
return bool(_native.valid(self.index, self.token))
|
|
95
|
+
|
|
96
|
+
def _info(self):
|
|
97
|
+
_manager()
|
|
98
|
+
return _native.player_info(self.index, self.token)
|
|
99
|
+
|
|
100
|
+
@property
|
|
101
|
+
def name(self):
|
|
102
|
+
"""RU:
|
|
103
|
+
Текущее имя игрока.
|
|
104
|
+
|
|
105
|
+
EN:
|
|
106
|
+
Current player name."""
|
|
107
|
+
return self._info()['name']
|
|
108
|
+
|
|
109
|
+
@property
|
|
110
|
+
def steam_id(self):
|
|
111
|
+
"""RU:
|
|
112
|
+
Идентификатор Steam подключения.
|
|
113
|
+
|
|
114
|
+
EN:
|
|
115
|
+
Connection Steam ID."""
|
|
116
|
+
return self._info()['steam_id']
|
|
117
|
+
|
|
118
|
+
@property
|
|
119
|
+
def userid(self):
|
|
120
|
+
"""RU:
|
|
121
|
+
Серверный userid подключения.
|
|
122
|
+
|
|
123
|
+
EN:
|
|
124
|
+
Server userid for this connection."""
|
|
125
|
+
return self._info()['userid']
|
|
126
|
+
|
|
127
|
+
@property
|
|
128
|
+
def alive(self):
|
|
129
|
+
"""RU:
|
|
130
|
+
Жив ли игрок.
|
|
131
|
+
|
|
132
|
+
EN:
|
|
133
|
+
Whether the player is alive."""
|
|
134
|
+
return bool(self._info()['alive'])
|
|
135
|
+
|
|
136
|
+
@property
|
|
137
|
+
def observing(self):
|
|
138
|
+
"""RU:
|
|
139
|
+
Режим наблюдения, включая мёртвых игроков.
|
|
140
|
+
Примечания реализации / Implementation notes:
|
|
141
|
+
In observer mode, including spectators and dead players watching others.
|
|
142
|
+
|
|
143
|
+
EN:
|
|
144
|
+
Observer mode, including dead players watching others.
|
|
145
|
+
Implementation notes / Примечания реализации:
|
|
146
|
+
In observer mode, including spectators and dead players watching others."""
|
|
147
|
+
return bool(self._info()['observing'])
|
|
148
|
+
|
|
149
|
+
@property
|
|
150
|
+
def health(self):
|
|
151
|
+
"""RU:
|
|
152
|
+
Количество здоровья игрока.
|
|
153
|
+
|
|
154
|
+
EN:
|
|
155
|
+
The player's health."""
|
|
156
|
+
return self._info()['health']
|
|
157
|
+
|
|
158
|
+
@health.setter
|
|
159
|
+
def health(self, value):
|
|
160
|
+
"""RU:
|
|
161
|
+
API PyMod: Player.health. Сигнатура и исходные примечания приведены ниже.
|
|
162
|
+
Параметры: value.
|
|
163
|
+
|
|
164
|
+
EN:
|
|
165
|
+
PyMod API: Player.health. See the signature and original implementation notes below.
|
|
166
|
+
Parameters: value."""
|
|
167
|
+
_manager()
|
|
168
|
+
value = float(value)
|
|
169
|
+
if not math.isfinite(value) or not 1 <= value <= 100000:
|
|
170
|
+
raise ValueError('health must be finite and between 1 and 100000')
|
|
171
|
+
_native.set_health(self.index, self.token, value)
|
|
172
|
+
|
|
173
|
+
@property
|
|
174
|
+
def armor(self):
|
|
175
|
+
"""RU:
|
|
176
|
+
Количество брони игрока.
|
|
177
|
+
|
|
178
|
+
EN:
|
|
179
|
+
The player's armor."""
|
|
180
|
+
return self._info()['armor']
|
|
181
|
+
|
|
182
|
+
@armor.setter
|
|
183
|
+
def armor(self, value):
|
|
184
|
+
"""RU:
|
|
185
|
+
API PyMod: Player.armor. Сигнатура и исходные примечания приведены ниже.
|
|
186
|
+
Параметры: value.
|
|
187
|
+
|
|
188
|
+
EN:
|
|
189
|
+
PyMod API: Player.armor. See the signature and original implementation notes below.
|
|
190
|
+
Parameters: value."""
|
|
191
|
+
_manager()
|
|
192
|
+
value = float(value)
|
|
193
|
+
if not math.isfinite(value) or not 0 <= value <= 100000:
|
|
194
|
+
raise ValueError('armor must be finite and between 0 and 100000')
|
|
195
|
+
_native.set_armor(self.index, self.token, value)
|
|
196
|
+
|
|
197
|
+
def say(self, message, *, color=None, prefix=None, **values):
|
|
198
|
+
"""RU:
|
|
199
|
+
Отправляет сообщение игроку. color — цвет, prefix — префикс этого сообщения; цвета чата ограничены палитрой CS.
|
|
200
|
+
Параметры: message, color, prefix.
|
|
201
|
+
|
|
202
|
+
EN:
|
|
203
|
+
Sends a player a chat message. color sets color and prefix sets this message's prefix; CS chat has a limited palette.
|
|
204
|
+
Parameters: message, color, prefix."""
|
|
205
|
+
from ._chat import send
|
|
206
|
+
send(self, message, color=color, prefix=prefix, **values)
|
|
207
|
+
message = say
|
|
208
|
+
|
|
209
|
+
def in_group(self, name):
|
|
210
|
+
"""RU:
|
|
211
|
+
Проверяет членство игрока в указанной группе.
|
|
212
|
+
Параметры: name.
|
|
213
|
+
|
|
214
|
+
EN:
|
|
215
|
+
Checks whether the player belongs to the named group.
|
|
216
|
+
Parameters: name."""
|
|
217
|
+
return name in permissions.groups(self)
|
|
218
|
+
|
|
219
|
+
def sound(self, resource):
|
|
220
|
+
"""RU:
|
|
221
|
+
API PyMod: Player.sound. Сигнатура и исходные примечания приведены ниже.
|
|
222
|
+
Параметры: resource.
|
|
223
|
+
|
|
224
|
+
EN:
|
|
225
|
+
PyMod API: Player.sound. See the signature and original implementation notes below.
|
|
226
|
+
Parameters: resource."""
|
|
227
|
+
from ._assets import Sound
|
|
228
|
+
return (resource if isinstance(resource, Sound) else Sound(resource)).play(self)
|
|
229
|
+
|
|
230
|
+
def hud(self, text, *, color=None, seconds=3, position=None, x=-1, y=0.2, channel=None):
|
|
231
|
+
"""RU:
|
|
232
|
+
Показывает HUD-сообщение: text — текст, seconds — секунды, position — Position или имя, color — Color/HEX/RGB.
|
|
233
|
+
Параметры: text, color, seconds, position, x, y, channel.
|
|
234
|
+
Примечания реализации / Implementation notes:
|
|
235
|
+
One line of plugin code for a colored HUD notice; accepts RGB or HEX.
|
|
236
|
+
|
|
237
|
+
EN:
|
|
238
|
+
Shows a HUD message: text, seconds of visibility, position as Position or a name, and color as Color/HEX/RGB.
|
|
239
|
+
Parameters: text, color, seconds, position, x, y, channel.
|
|
240
|
+
Implementation notes / Примечания реализации:
|
|
241
|
+
One line of plugin code for a colored HUD notice; accepts RGB or HEX."""
|
|
242
|
+
return Hud(color=color or Color.Cyan(), hold=seconds, position=position, x=x, y=y, fade_in=0, fade_out=0).show(self, text, channel=channel)
|
|
243
|
+
|
|
244
|
+
def console(self, message):
|
|
245
|
+
"""RU:
|
|
246
|
+
Печатает сообщение в игровой консоли игрока.
|
|
247
|
+
Параметры: message.
|
|
248
|
+
|
|
249
|
+
EN:
|
|
250
|
+
Prints a message in the player's game console.
|
|
251
|
+
Parameters: message."""
|
|
252
|
+
_manager()
|
|
253
|
+
_native.console_print(self.index, self.token, str(message))
|
|
254
|
+
|
|
255
|
+
def kick(self, reason='Kicked by administrator'):
|
|
256
|
+
"""RU:
|
|
257
|
+
Отключает конкретное подключение игрока с указанной причиной.
|
|
258
|
+
Параметры: reason.
|
|
259
|
+
|
|
260
|
+
EN:
|
|
261
|
+
Disconnects this exact player connection with the supplied reason.
|
|
262
|
+
Parameters: reason."""
|
|
263
|
+
userid = self.userid
|
|
264
|
+
if userid <= 0:
|
|
265
|
+
raise ValueError('Player has no engine userid')
|
|
266
|
+
server.command('kick', f'#{userid}', reason)
|
|
267
|
+
|
|
268
|
+
def has_permission(self, permission):
|
|
269
|
+
"""RU:
|
|
270
|
+
Проверяет наличие права у игрока с учётом групп и срока действия.
|
|
271
|
+
Параметры: permission.
|
|
272
|
+
|
|
273
|
+
EN:
|
|
274
|
+
Checks a player's permission including group membership and expiration.
|
|
275
|
+
Parameters: permission."""
|
|
276
|
+
return permissions.has(self, permission)
|
|
277
|
+
|
|
278
|
+
def can(self, permission, *, description=None):
|
|
279
|
+
"""RU:
|
|
280
|
+
Проверяет прямые права игрока и права его групп. Регистрирует неизвестное право, но не выдаёт его.
|
|
281
|
+
Параметры: permission, description.
|
|
282
|
+
Примечания реализации / Implementation notes:
|
|
283
|
+
Effective permission: direct + inherited groups, with live expiry/revocation.
|
|
284
|
+
|
|
285
|
+
EN:
|
|
286
|
+
Checks direct and inherited group permissions. Registers an unknown permission but never grants it.
|
|
287
|
+
Parameters: permission, description.
|
|
288
|
+
Implementation notes / Примечания реализации:
|
|
289
|
+
Effective permission: direct + inherited groups, with live expiry/revocation."""
|
|
290
|
+
from ._easy import remember
|
|
291
|
+
remember(permission)
|
|
292
|
+
if description is not None:
|
|
293
|
+
permissions.register(permission, description)
|
|
294
|
+
return permissions.has(self, permission)
|
|
295
|
+
|
|
296
|
+
def can_any(self, *names):
|
|
297
|
+
"""RU:
|
|
298
|
+
Истина, если у игрока есть хотя бы одно из перечисленных прав.
|
|
299
|
+
Примечания реализации / Implementation notes:
|
|
300
|
+
Any exact permission; all names are automatically registered.
|
|
301
|
+
|
|
302
|
+
EN:
|
|
303
|
+
True if the player has at least one of the listed permissions.
|
|
304
|
+
Implementation notes / Примечания реализации:
|
|
305
|
+
Any exact permission; all names are automatically registered."""
|
|
306
|
+
return any(tuple((self.can(name) for name in names)))
|
|
307
|
+
|
|
308
|
+
def can_all(self, *names):
|
|
309
|
+
"""RU:
|
|
310
|
+
Истина, если у игрока есть все перечисленные права.
|
|
311
|
+
Примечания реализации / Implementation notes:
|
|
312
|
+
Every exact permission; an empty request never grants access.
|
|
313
|
+
|
|
314
|
+
EN:
|
|
315
|
+
True if the player has every listed permission.
|
|
316
|
+
Implementation notes / Примечания реализации:
|
|
317
|
+
Every exact permission; an empty request never grants access."""
|
|
318
|
+
return bool(names) and all(tuple((self.can(name) for name in names)))
|
|
319
|
+
|
|
320
|
+
def heal(self, amount=100, *, maximum=None, damage_type=0):
|
|
321
|
+
"""RU:
|
|
322
|
+
Лечит игрока. Ограниченный вариант с maximum возвращает фактическую прибавку; обычный вызов использует GameDLL.
|
|
323
|
+
Параметры: amount, maximum, damage_type.
|
|
324
|
+
Примечания реализации / Implementation notes:
|
|
325
|
+
Normal healing uses GameDLL; explicit maximum permits bounded bonus HP.
|
|
326
|
+
|
|
327
|
+
EN:
|
|
328
|
+
Heals a player. The bounded maximum variant returns the actual increase; the ordinary call uses GameDLL.
|
|
329
|
+
Parameters: amount, maximum, damage_type.
|
|
330
|
+
Implementation notes / Примечания реализации:
|
|
331
|
+
Normal healing uses GameDLL; explicit maximum permits bounded bonus HP."""
|
|
332
|
+
if maximum is None:
|
|
333
|
+
return PlayerActions.heal(self, amount, damage_type=damage_type)
|
|
334
|
+
from ._easy import increase
|
|
335
|
+
return increase(self, 'health', amount, maximum)
|
|
336
|
+
|
|
337
|
+
def add_armor(self, amount=100, *, maximum=100):
|
|
338
|
+
"""RU:
|
|
339
|
+
Добавляет броню с ограничением maximum и возвращает фактическую прибавку.
|
|
340
|
+
Параметры: amount, maximum.
|
|
341
|
+
Примечания реализации / Implementation notes:
|
|
342
|
+
Add armor points up to maximum; helmet/equipment type is unchanged.
|
|
343
|
+
|
|
344
|
+
EN:
|
|
345
|
+
Adds armor up to maximum and returns the actual increase.
|
|
346
|
+
Parameters: amount, maximum.
|
|
347
|
+
Implementation notes / Примечания реализации:
|
|
348
|
+
Add armor points up to maximum; helmet/equipment type is unchanged."""
|
|
349
|
+
from ._easy import increase
|
|
350
|
+
return increase(self, 'armor', amount, maximum)
|
|
351
|
+
|
|
352
|
+
def motd(self, content, title='PyMod'):
|
|
353
|
+
"""RU:
|
|
354
|
+
Открывает MOTD игрока с указанным содержимым и заголовком.
|
|
355
|
+
Параметры: content, title.
|
|
356
|
+
Примечания реализации / Implementation notes:
|
|
357
|
+
Send HTML/text/URL (1..1200 UTF-8 bytes); rendering depends on client.
|
|
358
|
+
|
|
359
|
+
EN:
|
|
360
|
+
Opens the player's MOTD using the supplied content and title.
|
|
361
|
+
Parameters: content, title.
|
|
362
|
+
Implementation notes / Примечания реализации:
|
|
363
|
+
Send HTML/text/URL (1..1200 UTF-8 bytes); rendering depends on client."""
|
|
364
|
+
_manager()
|
|
365
|
+
if not isinstance(content, str) or not isinstance(title, str) or '\x00' in content or ('\x00' in title):
|
|
366
|
+
raise ValueError('MOTD content/title must be strings without NUL')
|
|
367
|
+
_native.motd(self.index, self.token, content, title)
|
|
368
|
+
|
|
369
|
+
@dataclass(frozen=True)
|
|
370
|
+
class Disconnect:
|
|
371
|
+
"""RU:
|
|
372
|
+
API PyMod: Disconnect. Сигнатура и исходные примечания приведены ниже.
|
|
373
|
+
Примечания реализации / Implementation notes:
|
|
374
|
+
Snapshot: the departed player is no longer a valid game handle.
|
|
375
|
+
|
|
376
|
+
EN:
|
|
377
|
+
PyMod API: Disconnect. See the signature and original implementation notes below.
|
|
378
|
+
Implementation notes / Примечания реализации:
|
|
379
|
+
Snapshot: the departed player is no longer a valid game handle."""
|
|
380
|
+
index: int
|
|
381
|
+
name: str
|
|
382
|
+
steam_id: str
|
|
383
|
+
userid: int
|
|
384
|
+
|
|
385
|
+
def players(*, alive=None, team=None, permission=None, exclude=None):
|
|
386
|
+
"""RU:
|
|
387
|
+
API PyMod: players. Сигнатура и исходные примечания приведены ниже.
|
|
388
|
+
Параметры: alive, team, permission, exclude.
|
|
389
|
+
|
|
390
|
+
EN:
|
|
391
|
+
PyMod API: players. See the signature and original implementation notes below.
|
|
392
|
+
Parameters: alive, team, permission, exclude."""
|
|
393
|
+
_manager()
|
|
394
|
+
if alive is not None and type(alive) is not bool:
|
|
395
|
+
raise ValueError('alive must be bool or None')
|
|
396
|
+
if team is not None and team not in ('CT', 'TERRORIST', 'SPECTATOR', 'UNASSIGNED'):
|
|
397
|
+
raise ValueError('Invalid team')
|
|
398
|
+
if exclude is not None and (not isinstance(exclude, Player)):
|
|
399
|
+
raise TypeError('exclude must be Player')
|
|
400
|
+
if permission is not None:
|
|
401
|
+
from ._easy import remember
|
|
402
|
+
remember(permission)
|
|
403
|
+
result = []
|
|
404
|
+
for index, token in _native.players():
|
|
405
|
+
p = Player(index, token)
|
|
406
|
+
if exclude is not None and (index, token) == (exclude.index, exclude.token):
|
|
407
|
+
continue
|
|
408
|
+
if alive is not None and p.alive != alive:
|
|
409
|
+
continue
|
|
410
|
+
if team is not None and p.team != team:
|
|
411
|
+
continue
|
|
412
|
+
if permission is not None and (not permissions.has(p, permission)):
|
|
413
|
+
continue
|
|
414
|
+
result.append(p)
|
|
415
|
+
return result
|
|
416
|
+
|
|
417
|
+
def broadcast(message, **options):
|
|
418
|
+
"""RU:
|
|
419
|
+
API PyMod: broadcast. Сигнатура и исходные примечания приведены ниже.
|
|
420
|
+
Параметры: message.
|
|
421
|
+
|
|
422
|
+
EN:
|
|
423
|
+
PyMod API: broadcast. See the signature and original implementation notes below.
|
|
424
|
+
Parameters: message."""
|
|
425
|
+
for player in players():
|
|
426
|
+
player.say(message, **options)
|
|
427
|
+
|
|
428
|
+
def cvar(name, value=None):
|
|
429
|
+
"""RU:
|
|
430
|
+
API PyMod: cvar. Сигнатура и исходные примечания приведены ниже.
|
|
431
|
+
Параметры: name, value.
|
|
432
|
+
|
|
433
|
+
EN:
|
|
434
|
+
PyMod API: cvar. See the signature and original implementation notes below.
|
|
435
|
+
Parameters: name, value."""
|
|
436
|
+
_manager()
|
|
437
|
+
if value is None:
|
|
438
|
+
return _native.cvar_get(str(name))
|
|
439
|
+
_native.cvar_set(str(name), str(value))
|
|
440
|
+
|
|
441
|
+
class events:
|
|
442
|
+
"""RU:
|
|
443
|
+
API PyMod: events. Сигнатура и исходные примечания приведены ниже.
|
|
444
|
+
|
|
445
|
+
EN:
|
|
446
|
+
PyMod API: events. See the signature and original implementation notes below."""
|
|
447
|
+
|
|
448
|
+
@staticmethod
|
|
449
|
+
def on(name):
|
|
450
|
+
"""RU:
|
|
451
|
+
API PyMod: events.on. Сигнатура и исходные примечания приведены ниже.
|
|
452
|
+
Параметры: name.
|
|
453
|
+
Примечания реализации / Implementation notes:
|
|
454
|
+
Events: map_start(str), player_join(Player), player_disconnect(Disconnect).
|
|
455
|
+
|
|
456
|
+
EN:
|
|
457
|
+
PyMod API: events.on. See the signature and original implementation notes below.
|
|
458
|
+
Parameters: name.
|
|
459
|
+
Implementation notes / Примечания реализации:
|
|
460
|
+
Events: map_start(str), player_join(Player), player_disconnect(Disconnect)."""
|
|
461
|
+
|
|
462
|
+
def decorate(callback):
|
|
463
|
+
_manager().register_event(name, callback)
|
|
464
|
+
return callback
|
|
465
|
+
return decorate
|
|
466
|
+
|
|
467
|
+
@staticmethod
|
|
468
|
+
def filter(name):
|
|
469
|
+
"""RU:
|
|
470
|
+
API PyMod: events.filter. Сигнатура и исходные примечания приведены ниже.
|
|
471
|
+
Параметры: name.
|
|
472
|
+
Примечания реализации / Implementation notes:
|
|
473
|
+
Synchronous filter: True consumes. chat_format runs after chat moderation
|
|
474
|
+
and only for messages that are not registered chat commands.
|
|
475
|
+
|
|
476
|
+
EN:
|
|
477
|
+
PyMod API: events.filter. See the signature and original implementation notes below.
|
|
478
|
+
Parameters: name.
|
|
479
|
+
Implementation notes / Примечания реализации:
|
|
480
|
+
Synchronous filter: True consumes. chat_format runs after chat moderation
|
|
481
|
+
and only for messages that are not registered chat commands."""
|
|
482
|
+
|
|
483
|
+
def decorate(callback):
|
|
484
|
+
_manager().register_filter(name, callback)
|
|
485
|
+
return callback
|
|
486
|
+
return decorate
|
|
487
|
+
|
|
488
|
+
class commands:
|
|
489
|
+
"""RU:
|
|
490
|
+
API PyMod: commands. Сигнатура и исходные примечания приведены ниже.
|
|
491
|
+
|
|
492
|
+
EN:
|
|
493
|
+
PyMod API: commands. See the signature and original implementation notes below."""
|
|
494
|
+
|
|
495
|
+
@staticmethod
|
|
496
|
+
def client(name, *, permission=None):
|
|
497
|
+
"""RU:
|
|
498
|
+
API PyMod: commands.client. Сигнатура и исходные примечания приведены ниже.
|
|
499
|
+
Параметры: name, permission.
|
|
500
|
+
Примечания реализации / Implementation notes:
|
|
501
|
+
Client-only command (including legacy binds); callback(context, args).
|
|
502
|
+
|
|
503
|
+
Uses an owned ClientCommand filter, so unloading restores engine handling.
|
|
504
|
+
Server/RCON commands continue to use the py_ namespace via console().
|
|
505
|
+
|
|
506
|
+
EN:
|
|
507
|
+
PyMod API: commands.client. See the signature and original implementation notes below.
|
|
508
|
+
Parameters: name, permission.
|
|
509
|
+
Implementation notes / Примечания реализации:
|
|
510
|
+
Client-only command (including legacy binds); callback(context, args).
|
|
511
|
+
|
|
512
|
+
Uses an owned ClientCommand filter, so unloading restores engine handling.
|
|
513
|
+
Server/RCON commands continue to use the py_ namespace via console()."""
|
|
514
|
+
import re
|
|
515
|
+
if not isinstance(name, str) or not re.fullmatch('[+\\-]?[a-zA-Z_][a-zA-Z0-9_]{0,62}', name):
|
|
516
|
+
raise ValueError('Invalid client command name')
|
|
517
|
+
if name.lower() in {'say', 'say_team', 'menuselect', 'pymod', 'pymodmenu'}:
|
|
518
|
+
raise ValueError('Use the dedicated chat/menu/core command API')
|
|
519
|
+
if permission is not None:
|
|
520
|
+
from ._services import validate_permission
|
|
521
|
+
validate_permission(permission)
|
|
522
|
+
|
|
523
|
+
def decorate(callback):
|
|
524
|
+
if not callable(callback):
|
|
525
|
+
raise TypeError('Command callback must be callable')
|
|
526
|
+
|
|
527
|
+
def intercept(player, command, args):
|
|
528
|
+
if command.lower() != name.lower():
|
|
529
|
+
return False
|
|
530
|
+
if permission and (not player.has_permission(permission)):
|
|
531
|
+
player.console('Missing permission: ' + permission)
|
|
532
|
+
return True
|
|
533
|
+
|
|
534
|
+
async def invoke():
|
|
535
|
+
if not player.connected:
|
|
536
|
+
return
|
|
537
|
+
try:
|
|
538
|
+
if permission:
|
|
539
|
+
permissions.require(player, permission)
|
|
540
|
+
from ._services import CommandContext
|
|
541
|
+
result = callback(CommandContext(player), list(args))
|
|
542
|
+
if inspect.isawaitable(result):
|
|
543
|
+
await result
|
|
544
|
+
except (ValueError, PermissionError) as error:
|
|
545
|
+
if player.connected:
|
|
546
|
+
player.console(str(error)[:200])
|
|
547
|
+
timers.after(0, invoke)
|
|
548
|
+
return True
|
|
549
|
+
manager = _manager()
|
|
550
|
+
if any((getattr(cb, 'client_command_name', None) == name.lower() for _, cb in manager.client_filters)):
|
|
551
|
+
raise ValueError('Client command already registered: ' + name)
|
|
552
|
+
intercept.client_command_name = name.lower()
|
|
553
|
+
manager.register_filter('client_command', intercept)
|
|
554
|
+
return callback
|
|
555
|
+
return decorate
|
|
556
|
+
|
|
557
|
+
@staticmethod
|
|
558
|
+
def chat(name, *, consume=True, permission=None, help=''):
|
|
559
|
+
"""RU:
|
|
560
|
+
API PyMod: commands.chat. Сигнатура и исходные примечания приведены ниже.
|
|
561
|
+
Параметры: name, consume, permission, help.
|
|
562
|
+
Примечания реализации / Implementation notes:
|
|
563
|
+
Handler(player, args: list[str]); consume decision is synchronous.
|
|
564
|
+
|
|
565
|
+
EN:
|
|
566
|
+
PyMod API: commands.chat. See the signature and original implementation notes below.
|
|
567
|
+
Parameters: name, consume, permission, help.
|
|
568
|
+
Implementation notes / Примечания реализации:
|
|
569
|
+
Handler(player, args: list[str]); consume decision is synchronous."""
|
|
570
|
+
|
|
571
|
+
def decorate(callback):
|
|
572
|
+
_manager().register_command(name, callback, bool(consume), permission, help)
|
|
573
|
+
return callback
|
|
574
|
+
return decorate
|
|
575
|
+
|
|
576
|
+
@staticmethod
|
|
577
|
+
def console(name, *, permission=None, help=''):
|
|
578
|
+
"""RU:
|
|
579
|
+
Печатает сообщение в игровой консоли игрока.
|
|
580
|
+
Параметры: name, permission, help.
|
|
581
|
+
Примечания реализации / Implementation notes:
|
|
582
|
+
Handler(context, args); available in both client and server console.
|
|
583
|
+
|
|
584
|
+
EN:
|
|
585
|
+
Prints a message in the player's game console.
|
|
586
|
+
Parameters: name, permission, help.
|
|
587
|
+
Implementation notes / Примечания реализации:
|
|
588
|
+
Handler(context, args); available in both client and server console."""
|
|
589
|
+
|
|
590
|
+
def decorate(callback):
|
|
591
|
+
_manager().register_console(name, callback, permission, help)
|
|
592
|
+
return callback
|
|
593
|
+
return decorate
|
|
594
|
+
|
|
595
|
+
@staticmethod
|
|
596
|
+
def catalog(player=None):
|
|
597
|
+
"""RU:
|
|
598
|
+
API PyMod: commands.catalog. Сигнатура и исходные примечания приведены ниже.
|
|
599
|
+
Параметры: player.
|
|
600
|
+
|
|
601
|
+
EN:
|
|
602
|
+
PyMod API: commands.catalog. See the signature and original implementation notes below.
|
|
603
|
+
Parameters: player."""
|
|
604
|
+
return _manager().command_catalog(player)
|
|
605
|
+
|
|
606
|
+
class timers:
|
|
607
|
+
"""RU:
|
|
608
|
+
API PyMod: timers. Сигнатура и исходные примечания приведены ниже.
|
|
609
|
+
|
|
610
|
+
EN:
|
|
611
|
+
PyMod API: timers. See the signature and original implementation notes below."""
|
|
612
|
+
|
|
613
|
+
@staticmethod
|
|
614
|
+
def every(seconds):
|
|
615
|
+
"""RU:
|
|
616
|
+
Запускает метод периодически с интервалом в секундах, пока плагин активен.
|
|
617
|
+
Параметры: seconds.
|
|
618
|
+
Примечания реализации / Implementation notes:
|
|
619
|
+
A non-overlapping repeating async timer, restarted on each map.
|
|
620
|
+
|
|
621
|
+
EN:
|
|
622
|
+
Runs a method periodically at the given interval in seconds while the plugin is active.
|
|
623
|
+
Parameters: seconds.
|
|
624
|
+
Implementation notes / Примечания реализации:
|
|
625
|
+
A non-overlapping repeating async timer, restarted on each map."""
|
|
626
|
+
seconds = float(seconds)
|
|
627
|
+
if not math.isfinite(seconds) or seconds < 0.05:
|
|
628
|
+
raise ValueError('timer interval must be finite and >= 0.05 seconds')
|
|
629
|
+
|
|
630
|
+
def decorate(callback):
|
|
631
|
+
_manager().register_timer(seconds, callback)
|
|
632
|
+
return callback
|
|
633
|
+
return decorate
|
|
634
|
+
|
|
635
|
+
@staticmethod
|
|
636
|
+
def after(seconds, callback, *args):
|
|
637
|
+
"""RU:
|
|
638
|
+
API PyMod: timers.after. Сигнатура и исходные примечания приведены ниже.
|
|
639
|
+
Параметры: seconds, callback.
|
|
640
|
+
|
|
641
|
+
EN:
|
|
642
|
+
PyMod API: timers.after. See the signature and original implementation notes below.
|
|
643
|
+
Parameters: seconds, callback."""
|
|
644
|
+
seconds = float(seconds)
|
|
645
|
+
if not math.isfinite(seconds) or seconds < 0:
|
|
646
|
+
raise ValueError('delay must be finite and nonnegative')
|
|
647
|
+
|
|
648
|
+
async def delayed():
|
|
649
|
+
await asyncio.sleep(seconds)
|
|
650
|
+
await _manager().invoke(callback, *args)
|
|
651
|
+
return create_task(delayed())
|
|
652
|
+
|
|
653
|
+
def create_task(coroutine):
|
|
654
|
+
"""RU:
|
|
655
|
+
API PyMod: create_task. Сигнатура и исходные примечания приведены ниже.
|
|
656
|
+
Параметры: coroutine.
|
|
657
|
+
Примечания реализации / Implementation notes:
|
|
658
|
+
Owned task: automatically cancelled on reload, unload and map change.
|
|
659
|
+
|
|
660
|
+
EN:
|
|
661
|
+
PyMod API: create_task. See the signature and original implementation notes below.
|
|
662
|
+
Parameters: coroutine.
|
|
663
|
+
Implementation notes / Примечания реализации:
|
|
664
|
+
Owned task: automatically cancelled on reload, unload and map change."""
|
|
665
|
+
return _manager().spawn(coroutine)
|
|
666
|
+
|
|
667
|
+
async def run_in_thread(function, /, *args, **kwargs):
|
|
668
|
+
"""RU:
|
|
669
|
+
API PyMod: run_in_thread. Сигнатура и исходные примечания приведены ниже.
|
|
670
|
+
Параметры: function.
|
|
671
|
+
Асинхронный метод: используйте await.
|
|
672
|
+
Примечания реализации / Implementation notes:
|
|
673
|
+
Run blocking I/O in a worker. Game APIs are prohibited in that worker.
|
|
674
|
+
|
|
675
|
+
Reload waits for the worker to finish. Always use I/O timeouts.
|
|
676
|
+
|
|
677
|
+
EN:
|
|
678
|
+
PyMod API: run_in_thread. See the signature and original implementation notes below.
|
|
679
|
+
Parameters: function.
|
|
680
|
+
Asynchronous method: use await.
|
|
681
|
+
Implementation notes / Примечания реализации:
|
|
682
|
+
Run blocking I/O in a worker. Game APIs are prohibited in that worker.
|
|
683
|
+
|
|
684
|
+
Reload waits for the worker to finish. Always use I/O timeouts."""
|
|
685
|
+
return await _manager().run_in_thread(function, *args, **kwargs)
|
|
686
|
+
|
|
687
|
+
async def http_get(url, *, timeout=5.0, max_bytes=1048576):
|
|
688
|
+
"""RU:
|
|
689
|
+
API PyMod: http_get. Сигнатура и исходные примечания приведены ниже.
|
|
690
|
+
Параметры: url, timeout, max_bytes.
|
|
691
|
+
Асинхронный метод: используйте await.
|
|
692
|
+
Примечания реализации / Implementation notes:
|
|
693
|
+
GET http(s); return bytes. Uses the bundled stdlib, no pip packages needed.
|
|
694
|
+
|
|
695
|
+
EN:
|
|
696
|
+
PyMod API: http_get. See the signature and original implementation notes below.
|
|
697
|
+
Parameters: url, timeout, max_bytes.
|
|
698
|
+
Asynchronous method: use await.
|
|
699
|
+
Implementation notes / Примечания реализации:
|
|
700
|
+
GET http(s); return bytes. Uses the bundled stdlib, no pip packages needed."""
|
|
701
|
+
if not isinstance(url, str) or not url.startswith(('https://', 'http://')):
|
|
702
|
+
raise ValueError('an http:// or https:// URL is required')
|
|
703
|
+
if not math.isfinite(timeout) or not 0 < timeout <= 60:
|
|
704
|
+
raise ValueError('timeout must be between 0 and 60 seconds')
|
|
705
|
+
if not isinstance(max_bytes, int) or not 1 <= max_bytes <= 16 * 1024 * 1024:
|
|
706
|
+
raise ValueError('max_bytes must be between 1 and 16777216')
|
|
707
|
+
|
|
708
|
+
def request():
|
|
709
|
+
with urllib.request.urlopen(url, timeout=timeout) as response:
|
|
710
|
+
data = response.read(max_bytes + 1)
|
|
711
|
+
if len(data) > max_bytes:
|
|
712
|
+
raise ValueError('HTTP response exceeds max_bytes')
|
|
713
|
+
return data
|
|
714
|
+
return await run_in_thread(request)
|
|
715
|
+
from ._services import CommandContext, config, storage, permissions, targeting, server
|
|
716
|
+
from ._database import database
|
|
717
|
+
from ._menus import Menu, MenuItem
|
|
718
|
+
from . import web
|
|
719
|
+
from ._hooks import hooks, HookResult
|
|
720
|
+
from ._entities import Entity, EntityState, entities, trace, Trace, Hull, Solid, sounds
|
|
721
|
+
from ._resources import resources
|
|
722
|
+
from ._cvars import cvars, Cvar, CvarFlags, CvarChange
|
|
723
|
+
from ._hud import Hud
|
|
724
|
+
from ._events import PlayerSpawn, PlayerDeath, RoundEvent, GameMessage
|
|
725
|
+
from ._cs import cs, CsInfo, CsContext, CsSnapshot, DamageType, CsHookContext, CsHookSnapshot
|
|
726
|
+
from ._cs_types import CsTrace, CsMovement, CsPhysent, GameRulesState, CsLifecycleRecord
|
|
727
|
+
from ._effects import effects
|
|
728
|
+
from ._messages import Packet
|
|
729
|
+
from ._plugins import services
|
|
730
|
+
from ._voice import voice
|
|
731
|
+
from ._chat import chat
|
|
732
|
+
from ._i18n import i18n, tr
|
|
733
|
+
from ._simple_db import SQLite, Table, Record
|
|
734
|
+
from ._assets import Model, Sound, Sprite, Music
|
|
735
|
+
from ._plugin import Plugin, Players, PlayerGroup, command, console_command, every, hook, listen, service, page
|
|
736
|
+
from . import hook_events
|
|
737
|
+
from ._hook_api import Event, HookEvent, HookSnapshot
|
|
738
|
+
from ._timing import Cooldown, chance, wait
|
|
739
|
+
from ._schema import Config, ConfigField
|
|
740
|
+
__all__ = ['log', 'PlayerMovement', 'Vector', 'Movement', 'Buttons', 'PlayerFlags', 'MoveType', 'Color', 'Position', 'PlayerActions', 'WeaponId', 'WeaponState', 'AmmoState', 'Rendering', 'PlayerStateHelpers', 'Team', 'Box', 'Zone', 'Player', 'Disconnect', 'players', 'broadcast', 'cvar', 'events', 'commands', 'timers', 'create_task', 'run_in_thread', 'http_get', 'CommandContext', 'config', 'storage', 'permissions', 'targeting', 'server', 'database', 'Menu', 'MenuItem', 'web', 'hooks', 'HookResult', 'Entity', 'EntityState', 'entities', 'trace', 'Trace', 'Hull', 'Solid', 'sounds', 'resources', 'cvars', 'Cvar', 'CvarFlags', 'CvarChange', 'Hud', 'PlayerSpawn', 'PlayerDeath', 'RoundEvent', 'GameMessage', 'cs', 'CsInfo', 'CsContext', 'CsSnapshot', 'DamageType', 'CsHookContext', 'CsHookSnapshot', 'CsTrace', 'CsMovement', 'CsPhysent', 'GameRulesState', 'CsLifecycleRecord', 'effects', 'Packet', 'services', 'voice', 'chat', 'i18n', 'tr', 'SQLite', 'Table', 'Record', 'Model', 'Sound', 'Sprite', 'Music', 'Plugin', 'Players', 'PlayerGroup', 'command', 'console_command', 'every', 'hook', 'listen', 'service', 'page', 'hook_events', 'Event', 'HookEvent', 'HookSnapshot', 'Cooldown', 'chance', 'wait', 'Config', 'ConfigField', 'ServerRequiredError']
|