ecapi-sdk 3.7.1__tar.gz → 3.7.3__tar.gz
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.
- {ecapi_sdk-3.7.1 → ecapi_sdk-3.7.3}/PKG-INFO +1 -1
- {ecapi_sdk-3.7.1 → ecapi_sdk-3.7.3}/pyproject.toml +1 -1
- {ecapi_sdk-3.7.1 → ecapi_sdk-3.7.3}/src/ecapi_sdk/client.py +508 -2
- {ecapi_sdk-3.7.1 → ecapi_sdk-3.7.3}/src/ecapi_sdk/client.pyi +632 -0
- {ecapi_sdk-3.7.1 → ecapi_sdk-3.7.3}/src/ecapi_sdk.egg-info/PKG-INFO +1 -1
- {ecapi_sdk-3.7.1 → ecapi_sdk-3.7.3}/README.md +0 -0
- {ecapi_sdk-3.7.1 → ecapi_sdk-3.7.3}/setup.cfg +0 -0
- {ecapi_sdk-3.7.1 → ecapi_sdk-3.7.3}/src/ecapi_sdk/__init__.py +0 -0
- {ecapi_sdk-3.7.1 → ecapi_sdk-3.7.3}/src/ecapi_sdk/py.typed +0 -0
- {ecapi_sdk-3.7.1 → ecapi_sdk-3.7.3}/src/ecapi_sdk.egg-info/SOURCES.txt +0 -0
- {ecapi_sdk-3.7.1 → ecapi_sdk-3.7.3}/src/ecapi_sdk.egg-info/dependency_links.txt +0 -0
- {ecapi_sdk-3.7.1 → ecapi_sdk-3.7.3}/src/ecapi_sdk.egg-info/top_level.txt +0 -0
|
@@ -4,6 +4,9 @@ from __future__ import annotations
|
|
|
4
4
|
import asyncio
|
|
5
5
|
import inspect
|
|
6
6
|
import json
|
|
7
|
+
import mimetypes
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from uuid import uuid4
|
|
7
10
|
from dataclasses import dataclass
|
|
8
11
|
from typing import Any, Callable, Dict, Mapping, Optional, Sequence, Tuple, Union
|
|
9
12
|
from urllib.error import HTTPError, URLError
|
|
@@ -21,6 +24,61 @@ REQUEST_OPTION_KEYS = {"body", "headers", "response_type", "auth"}
|
|
|
21
24
|
DEFAULT_BASE_URL = "https://api.easecation.net"
|
|
22
25
|
|
|
23
26
|
|
|
27
|
+
class _MultipartBody:
|
|
28
|
+
"""Stream ordinary files without buffering a large ZIP in memory."""
|
|
29
|
+
def __init__(self, payload: Mapping[str, Any], binary_fields: Sequence[str]) -> None:
|
|
30
|
+
self.boundary = "ecapi-" + uuid4().hex
|
|
31
|
+
self.parts = []
|
|
32
|
+
self.length = 0
|
|
33
|
+
for name, value in payload.items():
|
|
34
|
+
if value is None:
|
|
35
|
+
continue
|
|
36
|
+
if not name.replace("_", "").isalnum():
|
|
37
|
+
raise ValueError("Invalid multipart field name")
|
|
38
|
+
prefix = f'--{self.boundary}\r\nContent-Disposition: form-data; name="{name}"'
|
|
39
|
+
if name in binary_fields:
|
|
40
|
+
if isinstance(value, Path):
|
|
41
|
+
if not value.is_file():
|
|
42
|
+
raise ValueError("Upload path must be an ordinary file")
|
|
43
|
+
filename, data, size = value.name, value, value.stat().st_size
|
|
44
|
+
elif isinstance(value, tuple) and len(value) == 2 and isinstance(value[0], str) and isinstance(value[1], bytes):
|
|
45
|
+
filename, data = value
|
|
46
|
+
size = len(data)
|
|
47
|
+
else:
|
|
48
|
+
raise TypeError("Binary fields require pathlib.Path or (filename, bytes)")
|
|
49
|
+
if any(c in filename for c in '\r\n\0'):
|
|
50
|
+
raise ValueError("Invalid upload filename")
|
|
51
|
+
filename = filename.replace('"', '%22').replace('\\', '%5C')
|
|
52
|
+
mime = mimetypes.guess_type(filename)[0] or "application/octet-stream"
|
|
53
|
+
prefix += f'; filename="{filename}"\r\nContent-Type: {mime}'
|
|
54
|
+
else:
|
|
55
|
+
data = (str(value).lower() if isinstance(value, bool) else str(value)).encode("utf-8")
|
|
56
|
+
size = len(data)
|
|
57
|
+
prefix = (prefix + "\r\n\r\n").encode("utf-8")
|
|
58
|
+
self.parts.append((prefix, data, size))
|
|
59
|
+
self.length += len(prefix) + size + 2
|
|
60
|
+
self.suffix = f"--{self.boundary}--\r\n".encode("ascii")
|
|
61
|
+
self.length += len(self.suffix)
|
|
62
|
+
|
|
63
|
+
def __iter__(self):
|
|
64
|
+
for prefix, data, size in self.parts:
|
|
65
|
+
yield prefix
|
|
66
|
+
if isinstance(data, Path):
|
|
67
|
+
with data.open("rb") as handle:
|
|
68
|
+
remaining = size
|
|
69
|
+
while remaining:
|
|
70
|
+
chunk = handle.read(min(65536, remaining))
|
|
71
|
+
if not chunk:
|
|
72
|
+
raise OSError("Upload file changed while reading")
|
|
73
|
+
remaining -= len(chunk)
|
|
74
|
+
yield chunk
|
|
75
|
+
if handle.read(1):
|
|
76
|
+
raise OSError("Upload file changed while reading")
|
|
77
|
+
else:
|
|
78
|
+
yield data
|
|
79
|
+
yield b"\r\n"
|
|
80
|
+
yield self.suffix
|
|
81
|
+
|
|
24
82
|
class ECAPIError(Exception):
|
|
25
83
|
def __init__(self, message: str, status: int, payload: Any, url: str) -> None:
|
|
26
84
|
resolved_message = _extract_error_message(payload) or message
|
|
@@ -224,7 +282,11 @@ class _HttpClient:
|
|
|
224
282
|
merged_headers["Authorization"] = f"Bearer {token}"
|
|
225
283
|
|
|
226
284
|
request_data: Optional[bytes] = None
|
|
227
|
-
if body
|
|
285
|
+
if isinstance(body, _MultipartBody):
|
|
286
|
+
merged_headers["Content-Type"] = "multipart/form-data; boundary=" + body.boundary
|
|
287
|
+
merged_headers["Content-Length"] = str(body.length)
|
|
288
|
+
request_data = body
|
|
289
|
+
elif body is not None:
|
|
228
290
|
content_type = merged_headers.get("Content-Type", "")
|
|
229
291
|
if not content_type:
|
|
230
292
|
merged_headers["Content-Type"] = "application/json"
|
|
@@ -487,6 +549,7 @@ class AdminAPI(_BaseApi):
|
|
|
487
549
|
self.operation_log = AdminOperationLogAPI(http)
|
|
488
550
|
self.overwatch_case = AdminOverwatchCaseAPI(http)
|
|
489
551
|
self.overwatch_supervisor = AdminOverwatchSupervisorAPI(http)
|
|
552
|
+
self.parkour = AdminParkourAPI(http)
|
|
490
553
|
self.permission = AdminPermissionAPI(http)
|
|
491
554
|
self.player_data = AdminPlayerDataAPI(http)
|
|
492
555
|
self.player_merchandise = AdminPlayerMerchandiseAPI(http)
|
|
@@ -494,6 +557,7 @@ class AdminAPI(_BaseApi):
|
|
|
494
557
|
self.player_wallet = AdminPlayerWalletAPI(http)
|
|
495
558
|
self.punishment = AdminPunishmentAPI(http)
|
|
496
559
|
self.source_account_binding = AdminSourceAccountBindingAPI(http)
|
|
560
|
+
self.sp_workbench = AdminSpWorkbenchAPI(http)
|
|
497
561
|
self.vote_reward_mail = AdminVoteRewardMailAPI(http)
|
|
498
562
|
|
|
499
563
|
class AdminAccountAPI(_BaseApi):
|
|
@@ -562,6 +626,15 @@ class AdminOverwatchSupervisorAPI(_BaseApi):
|
|
|
562
626
|
"""修改监管者资格"""
|
|
563
627
|
return self._patch(f"/admin/overwatch-supervisors/{quote(str(ecid), safe='')}", payload, **kwargs)
|
|
564
628
|
|
|
629
|
+
class AdminParkourAPI(_BaseApi):
|
|
630
|
+
def clear_community_scores(self, ecid: str, payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
631
|
+
"""清除社区版逐关成绩"""
|
|
632
|
+
return self._post(f"/admin/players/{quote(str(ecid), safe='')}/parkour/community-score-clears", payload, **kwargs)
|
|
633
|
+
|
|
634
|
+
def preview_community_score_clear(self, ecid: str, query: Optional[QueryParams] = None, **kwargs: Any) -> Any:
|
|
635
|
+
"""预览社区版逐关成绩清除范围"""
|
|
636
|
+
return self._get(f"/admin/players/{quote(str(ecid), safe='')}/parkour/community-score-clear-preview", query, **kwargs)
|
|
637
|
+
|
|
565
638
|
class AdminPermissionAPI(_BaseApi):
|
|
566
639
|
def delete_entitlement(self, ecid: str, entitlementKey: str, **kwargs: Any) -> Any:
|
|
567
640
|
"""删除玩家权益"""
|
|
@@ -660,6 +733,10 @@ class AdminPunishmentAPI(_BaseApi):
|
|
|
660
733
|
"""解除处罚"""
|
|
661
734
|
return self._delete(f"/admin/players/{quote(str(ecid), safe='')}/punishments/{quote(str(type), safe='')}", query, **kwargs)
|
|
662
735
|
|
|
736
|
+
def set_parkour_punishment(self, payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
737
|
+
"""设置老版跑酷天堂成绩惩罚"""
|
|
738
|
+
return self._post(f"/punishments/parkour", payload, **kwargs)
|
|
739
|
+
|
|
663
740
|
class AdminSourceAccountBindingAPI(_BaseApi):
|
|
664
741
|
def bind_account_player(self, xuid: str, payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
665
742
|
"""绑定或改绑来源账号到玩家"""
|
|
@@ -677,11 +754,53 @@ class AdminSourceAccountBindingAPI(_BaseApi):
|
|
|
677
754
|
"""解绑玩家名下全部来源账号"""
|
|
678
755
|
return self._delete(f"/admin/players/{quote(str(ecid), safe='')}/source-accounts", None, **kwargs)
|
|
679
756
|
|
|
757
|
+
class AdminSpWorkbenchAPI(_BaseApi):
|
|
758
|
+
def capabilities(self, **kwargs: Any) -> Any:
|
|
759
|
+
"""只读查询 SP 专用进度执行能力"""
|
|
760
|
+
return self._get(f"/admin/sp/progress/capabilities", None, **kwargs)
|
|
761
|
+
|
|
762
|
+
def progress(self, payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
763
|
+
"""执行 SP 专用标准值进度修正"""
|
|
764
|
+
return self._post(f"/admin/sp/progress/operations", payload, **kwargs)
|
|
765
|
+
|
|
680
766
|
class AdminVoteRewardMailAPI(_BaseApi):
|
|
681
767
|
def create(self, payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
682
768
|
"""创建投票奖励邮件"""
|
|
683
769
|
return self._post(f"/admin/vote-reward-mails", payload, **kwargs)
|
|
684
770
|
|
|
771
|
+
class AnnouncementsAPI(_BaseApi):
|
|
772
|
+
def create(self, payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
773
|
+
"""新建公告"""
|
|
774
|
+
return self._post(f"/admin/announcements", payload, **kwargs)
|
|
775
|
+
|
|
776
|
+
def get(self, id: str, **kwargs: Any) -> Any:
|
|
777
|
+
"""读取公告管理详情"""
|
|
778
|
+
return self._get(f"/admin/announcements/{quote(str(id), safe='')}", None, **kwargs)
|
|
779
|
+
|
|
780
|
+
def list(self, **kwargs: Any) -> Any:
|
|
781
|
+
"""读取服内生效公告"""
|
|
782
|
+
return self._get(f"/announcements", None, **kwargs)
|
|
783
|
+
|
|
784
|
+
def list_get(self, query: Optional[QueryParams] = None, **kwargs: Any) -> Any:
|
|
785
|
+
"""查询公告管理列表"""
|
|
786
|
+
return self._get(f"/admin/announcements", query, **kwargs)
|
|
787
|
+
|
|
788
|
+
def move(self, id: str, payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
789
|
+
"""原子移动公告顺序"""
|
|
790
|
+
return self._post(f"/admin/announcements/{quote(str(id), safe='')}/move", payload, **kwargs)
|
|
791
|
+
|
|
792
|
+
def remove(self, id: str, query: Optional[QueryParams] = None, **kwargs: Any) -> Any:
|
|
793
|
+
"""公告移入回收站"""
|
|
794
|
+
return self._delete(f"/admin/announcements/{quote(str(id), safe='')}", query, **kwargs)
|
|
795
|
+
|
|
796
|
+
def restore(self, id: str, payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
797
|
+
"""恢复公告"""
|
|
798
|
+
return self._post(f"/admin/announcements/{quote(str(id), safe='')}/restore", payload, **kwargs)
|
|
799
|
+
|
|
800
|
+
def update(self, id: str, payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
801
|
+
"""修改公告"""
|
|
802
|
+
return self._patch(f"/admin/announcements/{quote(str(id), safe='')}", payload, **kwargs)
|
|
803
|
+
|
|
685
804
|
class AuditAPI(_BaseApi):
|
|
686
805
|
def get_admin_logs(self, query: Optional[QueryParams] = None, **kwargs: Any) -> Any:
|
|
687
806
|
"""查询管理员操作日志"""
|
|
@@ -732,6 +851,88 @@ class AuthAPI(_BaseApi):
|
|
|
732
851
|
"""刷新 Token"""
|
|
733
852
|
return self._post(f"/auth/refresh", payload, **kwargs)
|
|
734
853
|
|
|
854
|
+
class CatalogAPI(_BaseApi):
|
|
855
|
+
def __init__(self, http: _HttpClient) -> None:
|
|
856
|
+
super().__init__(http)
|
|
857
|
+
self.sync = CatalogSyncAPI(http)
|
|
858
|
+
|
|
859
|
+
def batch_update_products(self, payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
860
|
+
"""批量设置商品价格、稀有度或状态"""
|
|
861
|
+
return self._post(f"/catalog/products/batch-update", payload, **kwargs)
|
|
862
|
+
|
|
863
|
+
def change_product_status(self, id: Union[int, float], payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
864
|
+
"""商品状态流转"""
|
|
865
|
+
return self._post(f"/catalog/products/{quote(str(id), safe='')}/status", payload, **kwargs)
|
|
866
|
+
|
|
867
|
+
def create_product(self, payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
868
|
+
"""新建商品"""
|
|
869
|
+
return self._post(f"/catalog/products", payload, **kwargs)
|
|
870
|
+
|
|
871
|
+
def create_type(self, payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
872
|
+
"""新建商品类型"""
|
|
873
|
+
return self._post(f"/catalog/types", payload, **kwargs)
|
|
874
|
+
|
|
875
|
+
def delete_products(self, payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
876
|
+
"""移入商品回收站"""
|
|
877
|
+
return self._post(f"/catalog/products/batch-delete", payload, **kwargs)
|
|
878
|
+
|
|
879
|
+
def export_by_type(self, typeId: str, **kwargs: Any) -> Any:
|
|
880
|
+
"""按类型导出 CodeFunCore 商品配置 JSON"""
|
|
881
|
+
return self._get(f"/catalog/export/{quote(str(typeId), safe='')}", None, **kwargs)
|
|
882
|
+
|
|
883
|
+
def get_product_detail(self, id: Union[int, float], **kwargs: Any) -> Any:
|
|
884
|
+
"""获取商品详情"""
|
|
885
|
+
return self._get(f"/catalog/products/{quote(str(id), safe='')}", None, **kwargs)
|
|
886
|
+
|
|
887
|
+
def get_suit_parts(self, id: Union[int, float], **kwargs: Any) -> Any:
|
|
888
|
+
"""获取套装部件列表"""
|
|
889
|
+
return self._get(f"/catalog/products/{quote(str(id), safe='')}/parts", None, **kwargs)
|
|
890
|
+
|
|
891
|
+
def list_products(self, query: Optional[QueryParams] = None, **kwargs: Any) -> Any:
|
|
892
|
+
"""分页查询商品列表"""
|
|
893
|
+
return self._get(f"/catalog/products", query, **kwargs)
|
|
894
|
+
|
|
895
|
+
def list_published_products(self, query: Optional[QueryParams] = None, **kwargs: Any) -> Any:
|
|
896
|
+
"""分页查询正式服已上架商品"""
|
|
897
|
+
return self._get(f"/catalog/published-products", query, **kwargs)
|
|
898
|
+
|
|
899
|
+
def list_types(self, **kwargs: Any) -> Any:
|
|
900
|
+
"""获取商品类型列表"""
|
|
901
|
+
return self._get(f"/catalog/types", None, **kwargs)
|
|
902
|
+
|
|
903
|
+
def replace_suit_parts(self, id: Union[int, float], payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
904
|
+
"""整体替换套装部件列表"""
|
|
905
|
+
return self._put(f"/catalog/products/{quote(str(id), safe='')}/parts", payload, **kwargs)
|
|
906
|
+
|
|
907
|
+
def restore_products(self, payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
908
|
+
"""恢复回收站商品"""
|
|
909
|
+
return self._post(f"/catalog/products/batch-restore", payload, **kwargs)
|
|
910
|
+
|
|
911
|
+
def update_product(self, id: Union[int, float], payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
912
|
+
"""更新商品"""
|
|
913
|
+
return self._put(f"/catalog/products/{quote(str(id), safe='')}", payload, **kwargs)
|
|
914
|
+
|
|
915
|
+
def update_type(self, typeId: str, payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
916
|
+
"""更新商品类型"""
|
|
917
|
+
return self._put(f"/catalog/types/{quote(str(typeId), safe='')}", payload, **kwargs)
|
|
918
|
+
|
|
919
|
+
class CatalogSyncAPI(_BaseApi):
|
|
920
|
+
def apply(self, payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
921
|
+
"""把选中商品写入当前工作区商品文件"""
|
|
922
|
+
return self._post(f"/catalog-sync/apply", payload, **kwargs)
|
|
923
|
+
|
|
924
|
+
def conflicts(self, **kwargs: Any) -> Any:
|
|
925
|
+
"""列出被多个分支关联的商品"""
|
|
926
|
+
return self._get(f"/catalog-sync/conflicts", None, **kwargs)
|
|
927
|
+
|
|
928
|
+
def diff(self, **kwargs: Any) -> Any:
|
|
929
|
+
"""工作区商品文件与 catalog 生成结果的键级 diff"""
|
|
930
|
+
return self._get(f"/catalog-sync/diff", None, **kwargs)
|
|
931
|
+
|
|
932
|
+
def suggestions(self, **kwargs: Any) -> Any:
|
|
933
|
+
"""当前工作区的商品同步建议"""
|
|
934
|
+
return self._get(f"/catalog-sync/suggestions", None, **kwargs)
|
|
935
|
+
|
|
735
936
|
class GameLogAPI(_BaseApi):
|
|
736
937
|
def get_disaster_events(self, **kwargs: Any) -> Any:
|
|
737
938
|
"""获取灾难事件字典"""
|
|
@@ -773,6 +974,10 @@ class GameLogAPI(_BaseApi):
|
|
|
773
974
|
"""分页查询游戏玩家记录"""
|
|
774
975
|
return self._get(f"/game-logs/players", query, **kwargs)
|
|
775
976
|
|
|
977
|
+
def get_ze_statistics(self, query: Optional[QueryParams] = None, **kwargs: Any) -> Any:
|
|
978
|
+
"""生化大逃杀大盘统计"""
|
|
979
|
+
return self._get(f"/game-logs/zombieescape/statistics", query, **kwargs)
|
|
980
|
+
|
|
776
981
|
class EchoMelandAPI(_BaseApi):
|
|
777
982
|
def add_favorite(self, worldId: Union[int, float], ecid: str, **kwargs: Any) -> Any:
|
|
778
983
|
"""添加玩家家园收藏"""
|
|
@@ -888,11 +1093,289 @@ class LogOrderExchangeAPI(_BaseApi):
|
|
|
888
1093
|
"""分页查询兑换日志"""
|
|
889
1094
|
return self._get(f"/order-exchange-logs", query, **kwargs)
|
|
890
1095
|
|
|
1096
|
+
class LotteryAPI(_BaseApi):
|
|
1097
|
+
def cancel(self, id: str, **kwargs: Any) -> Any:
|
|
1098
|
+
"""取消不再需要的模拟"""
|
|
1099
|
+
return self._post(f"/lottery/simulations/{quote(str(id), safe='')}/cancel", None, **kwargs)
|
|
1100
|
+
|
|
1101
|
+
def convert(self, payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
1102
|
+
"""预览转换旧抽奖配置"""
|
|
1103
|
+
return self._post(f"/lottery/convert", payload, **kwargs)
|
|
1104
|
+
|
|
1105
|
+
def copy(self, id: str, payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
1106
|
+
"""复制为独立文件"""
|
|
1107
|
+
return self._post(f"/lottery/nodes/{quote(str(id), safe='')}/copy", payload, **kwargs)
|
|
1108
|
+
|
|
1109
|
+
def create(self, payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
1110
|
+
"""新建抽奖文件或目录"""
|
|
1111
|
+
return self._post(f"/lottery/nodes", payload, **kwargs)
|
|
1112
|
+
|
|
1113
|
+
def document(self, id: str, query: Optional[QueryParams] = None, **kwargs: Any) -> Any:
|
|
1114
|
+
"""读取当前或历史文件原文"""
|
|
1115
|
+
return self._get(f"/lottery/documents/{quote(str(id), safe='')}", query, **kwargs)
|
|
1116
|
+
|
|
1117
|
+
def download(self, payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
1118
|
+
"""下载单文件或完整配置文件组"""
|
|
1119
|
+
return self._post(f"/lottery/downloads", payload, **kwargs)
|
|
1120
|
+
|
|
1121
|
+
def history(self, id: str, query: Optional[QueryParams] = None, **kwargs: Any) -> Any:
|
|
1122
|
+
"""浏览文件保存历史"""
|
|
1123
|
+
return self._get(f"/lottery/documents/{quote(str(id), safe='')}/revisions", query, **kwargs)
|
|
1124
|
+
|
|
1125
|
+
def nodes(self, query: Optional[QueryParams] = None, **kwargs: Any) -> Any:
|
|
1126
|
+
"""列出抽奖文件与目录"""
|
|
1127
|
+
return self._get(f"/lottery/nodes", query, **kwargs)
|
|
1128
|
+
|
|
1129
|
+
def preview(self, payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
1130
|
+
"""解释下一抽的候选与保底"""
|
|
1131
|
+
return self._post(f"/lottery/preview", payload, **kwargs)
|
|
1132
|
+
|
|
1133
|
+
def product_options(self, payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
1134
|
+
"""解析所选商品的抽奖发放规格"""
|
|
1135
|
+
return self._post(f"/lottery/product-options", payload, **kwargs)
|
|
1136
|
+
|
|
1137
|
+
def restore(self, id: str, payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
1138
|
+
"""把历史内容恢复成新版本"""
|
|
1139
|
+
return self._post(f"/lottery/documents/{quote(str(id), safe='')}/restore", payload, **kwargs)
|
|
1140
|
+
|
|
1141
|
+
def save(self, id: str, payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
1142
|
+
"""手动保存YAML并创建历史版本"""
|
|
1143
|
+
return self._put(f"/lottery/documents/{quote(str(id), safe='')}", payload, **kwargs)
|
|
1144
|
+
|
|
1145
|
+
def simulation(self, id: str, **kwargs: Any) -> Any:
|
|
1146
|
+
"""查询抽奖模拟任务执行状态与奖励统计"""
|
|
1147
|
+
return self._get(f"/lottery/simulations/{quote(str(id), safe='')}", None, **kwargs)
|
|
1148
|
+
|
|
1149
|
+
def simulations(self, query: Optional[QueryParams] = None, **kwargs: Any) -> Any:
|
|
1150
|
+
"""查看最近的模拟记录"""
|
|
1151
|
+
return self._get(f"/lottery/simulations", query, **kwargs)
|
|
1152
|
+
|
|
1153
|
+
def start(self, payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
1154
|
+
"""提交异步模拟"""
|
|
1155
|
+
return self._post(f"/lottery/simulations", payload, **kwargs)
|
|
1156
|
+
|
|
1157
|
+
def templates(self, **kwargs: Any) -> Any:
|
|
1158
|
+
"""选择抽奖箱与公共池模板"""
|
|
1159
|
+
return self._get(f"/lottery/templates", None, **kwargs)
|
|
1160
|
+
|
|
1161
|
+
def update_node(self, id: str, payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
1162
|
+
"""重命名、移动或移入/恢复回收站"""
|
|
1163
|
+
return self._patch(f"/lottery/nodes/{quote(str(id), safe='')}", payload, **kwargs)
|
|
1164
|
+
|
|
1165
|
+
def validate(self, payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
1166
|
+
"""检查配置、商品引用及公共池依赖"""
|
|
1167
|
+
return self._post(f"/lottery/validate", payload, **kwargs)
|
|
1168
|
+
|
|
1169
|
+
class MinecraftDeveloperAPI(_BaseApi):
|
|
1170
|
+
def __init__(self, http: _HttpClient) -> None:
|
|
1171
|
+
super().__init__(http)
|
|
1172
|
+
self.messages = MinecraftMessagesAPI(http)
|
|
1173
|
+
self.mobile_mods = MinecraftMobileModsAPI(http)
|
|
1174
|
+
|
|
1175
|
+
def apply_self_test(self, edition: str, projectId: str, payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
1176
|
+
"""申请手游自测"""
|
|
1177
|
+
return self._post(f"/mcdev/projects/{quote(str(edition), safe='')}/{quote(str(projectId), safe='')}/self-test-applications", payload, **kwargs)
|
|
1178
|
+
|
|
1179
|
+
def cancel_self_test(self, edition: str, projectId: str, query: Optional[QueryParams] = None, **kwargs: Any) -> Any:
|
|
1180
|
+
"""取消手游自测"""
|
|
1181
|
+
return self._delete(f"/mcdev/projects/{quote(str(edition), safe='')}/{quote(str(projectId), safe='')}/self-test-applications/current", query, **kwargs)
|
|
1182
|
+
|
|
1183
|
+
def connect_session(self, payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
1184
|
+
"""连接官方登录会话"""
|
|
1185
|
+
return self._put(f"/mcdev/auth/session", payload, **kwargs)
|
|
1186
|
+
|
|
1187
|
+
def disconnect_session(self, **kwargs: Any) -> Any:
|
|
1188
|
+
"""断开 ECAPI 的网易会话"""
|
|
1189
|
+
return self._delete(f"/mcdev/auth/session", None, **kwargs)
|
|
1190
|
+
|
|
1191
|
+
def download_mobile_package(self, edition: str, projectId: str, **kwargs: Any) -> Any:
|
|
1192
|
+
"""下载手游资源包"""
|
|
1193
|
+
return self._get(f"/mcdev/projects/{quote(str(edition), safe='')}/{quote(str(projectId), safe='')}/mobile-package", None, response_type="bytes", **kwargs)
|
|
1194
|
+
|
|
1195
|
+
def get_project(self, edition: str, projectId: str, **kwargs: Any) -> Any:
|
|
1196
|
+
"""获取开发者项目"""
|
|
1197
|
+
return self._get(f"/mcdev/projects/{quote(str(edition), safe='')}/{quote(str(projectId), safe='')}", None, **kwargs)
|
|
1198
|
+
|
|
1199
|
+
def get_project_status(self, edition: str, projectId: str, **kwargs: Any) -> Any:
|
|
1200
|
+
"""查询项目异步状态"""
|
|
1201
|
+
return self._get(f"/mcdev/projects/{quote(str(edition), safe='')}/{quote(str(projectId), safe='')}/status", None, **kwargs)
|
|
1202
|
+
|
|
1203
|
+
def get_review_feedback(self, edition: str, projectId: str, **kwargs: Any) -> Any:
|
|
1204
|
+
"""查询项目审核意见"""
|
|
1205
|
+
return self._get(f"/mcdev/projects/{quote(str(edition), safe='')}/{quote(str(projectId), safe='')}/review-feedback", None, **kwargs)
|
|
1206
|
+
|
|
1207
|
+
def get_session(self, **kwargs: Any) -> Any:
|
|
1208
|
+
"""查询网易账号连接状态"""
|
|
1209
|
+
return self._get(f"/mcdev/auth/session", None, **kwargs)
|
|
1210
|
+
|
|
1211
|
+
def list_player_feedbacks(self, edition: str, projectId: str, query: Optional[QueryParams] = None, **kwargs: Any) -> Any:
|
|
1212
|
+
"""查询项目玩家反馈"""
|
|
1213
|
+
return self._get(f"/mcdev/projects/{quote(str(edition), safe='')}/{quote(str(projectId), safe='')}/player-feedbacks", query, **kwargs)
|
|
1214
|
+
|
|
1215
|
+
def list_project_orders(self, edition: str, projectId: str, query: Optional[QueryParams] = None, **kwargs: Any) -> Any:
|
|
1216
|
+
"""查询项目订单"""
|
|
1217
|
+
return self._get(f"/mcdev/projects/{quote(str(edition), safe='')}/{quote(str(projectId), safe='')}/orders", query, **kwargs)
|
|
1218
|
+
|
|
1219
|
+
def list_projects(self, query: Optional[QueryParams] = None, **kwargs: Any) -> Any:
|
|
1220
|
+
"""列出开发者项目"""
|
|
1221
|
+
return self._get(f"/mcdev/projects", query, **kwargs)
|
|
1222
|
+
|
|
1223
|
+
def publish_online(self, edition: str, projectId: str, payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
1224
|
+
"""上架审核通过项目"""
|
|
1225
|
+
return self._post(f"/mcdev/projects/{quote(str(edition), safe='')}/{quote(str(projectId), safe='')}/online-publications", payload, **kwargs)
|
|
1226
|
+
|
|
1227
|
+
def replace_resource_pack(self, edition: str, projectId: str, payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
1228
|
+
"""上传并替换资源包"""
|
|
1229
|
+
payload = _MultipartBody(payload, ['package'])
|
|
1230
|
+
return self._post(f"/mcdev/projects/{quote(str(edition), safe='')}/{quote(str(projectId), safe='')}/resource-packs", payload, **kwargs)
|
|
1231
|
+
|
|
1232
|
+
def revoke_review(self, edition: str, projectId: str, query: Optional[QueryParams] = None, **kwargs: Any) -> Any:
|
|
1233
|
+
"""撤销网易审核"""
|
|
1234
|
+
return self._delete(f"/mcdev/projects/{quote(str(edition), safe='')}/{quote(str(projectId), safe='')}/review-submissions/current", query, **kwargs)
|
|
1235
|
+
|
|
1236
|
+
def submit_review(self, edition: str, projectId: str, payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
1237
|
+
"""提交网易审核"""
|
|
1238
|
+
return self._post(f"/mcdev/projects/{quote(str(edition), safe='')}/{quote(str(projectId), safe='')}/review-submissions", payload, **kwargs)
|
|
1239
|
+
|
|
1240
|
+
class MinecraftMessagesAPI(_BaseApi):
|
|
1241
|
+
def detail(self, messageId: str, **kwargs: Any) -> Any:
|
|
1242
|
+
"""读取审核消息正文"""
|
|
1243
|
+
return self._get(f"/mcdev/messages/{quote(str(messageId), safe='')}", None, **kwargs)
|
|
1244
|
+
|
|
1245
|
+
def list(self, query: Optional[QueryParams] = None, **kwargs: Any) -> Any:
|
|
1246
|
+
"""分页查询审核与打包消息"""
|
|
1247
|
+
return self._get(f"/mcdev/messages", query, **kwargs)
|
|
1248
|
+
|
|
1249
|
+
def mark_read(self, payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
1250
|
+
"""标记指定审核消息已读"""
|
|
1251
|
+
return self._post(f"/mcdev/message-read-receipts", payload, **kwargs)
|
|
1252
|
+
|
|
1253
|
+
def unread(self, **kwargs: Any) -> Any:
|
|
1254
|
+
"""查询审核消息未读数量"""
|
|
1255
|
+
return self._get(f"/mcdev/messages/unread-count", None, **kwargs)
|
|
1256
|
+
|
|
1257
|
+
class MinecraftMobileModsAPI(_BaseApi):
|
|
1258
|
+
def apply_self_test(self, id: str, payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
1259
|
+
"""申请手机组件自测"""
|
|
1260
|
+
return self._post(f"/mcdev/mobile-mods/{quote(str(id), safe='')}/self-test-applications", payload, **kwargs)
|
|
1261
|
+
|
|
1262
|
+
def cancel_self_test(self, id: str, **kwargs: Any) -> Any:
|
|
1263
|
+
"""取消手机组件自测"""
|
|
1264
|
+
return self._delete(f"/mcdev/mobile-mods/{quote(str(id), safe='')}/self-test-applications/current", None, **kwargs)
|
|
1265
|
+
|
|
1266
|
+
def create(self, payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
1267
|
+
"""创建手机组件"""
|
|
1268
|
+
return self._post(f"/mcdev/mobile-mods", payload, **kwargs)
|
|
1269
|
+
|
|
1270
|
+
def detail(self, id: str, **kwargs: Any) -> Any:
|
|
1271
|
+
"""读取手机组件编辑内容"""
|
|
1272
|
+
return self._get(f"/mcdev/mobile-mods/{quote(str(id), safe='')}", None, **kwargs)
|
|
1273
|
+
|
|
1274
|
+
def feedback(self, id: str, **kwargs: Any) -> Any:
|
|
1275
|
+
"""读取手机组件审核意见"""
|
|
1276
|
+
return self._get(f"/mcdev/mobile-mods/{quote(str(id), safe='')}/review-feedback", None, **kwargs)
|
|
1277
|
+
|
|
1278
|
+
def list(self, query: Optional[QueryParams] = None, **kwargs: Any) -> Any:
|
|
1279
|
+
"""分页查询手机组件"""
|
|
1280
|
+
return self._get(f"/mcdev/mobile-mods", query, **kwargs)
|
|
1281
|
+
|
|
1282
|
+
def metadata(self, **kwargs: Any) -> Any:
|
|
1283
|
+
"""读取手机组件编辑规则"""
|
|
1284
|
+
return self._get(f"/mcdev/mobile-mods/metadata", None, **kwargs)
|
|
1285
|
+
|
|
1286
|
+
def preview_asset(self, id: str, assetId: str, **kwargs: Any) -> Any:
|
|
1287
|
+
"""读取手机组件素材"""
|
|
1288
|
+
return self._get(f"/mcdev/mobile-mods/{quote(str(id), safe='')}/assets/{quote(str(assetId), safe='')}/content", None, response_type="bytes", **kwargs)
|
|
1289
|
+
|
|
1290
|
+
def preview_upload(self, uploadId: str, **kwargs: Any) -> Any:
|
|
1291
|
+
"""预览已上传图片"""
|
|
1292
|
+
return self._get(f"/mcdev/mobile-mods/uploads/{quote(str(uploadId), safe='')}/content", None, response_type="bytes", **kwargs)
|
|
1293
|
+
|
|
1294
|
+
def revoke_review(self, id: str, **kwargs: Any) -> Any:
|
|
1295
|
+
"""撤销手机组件审核"""
|
|
1296
|
+
return self._delete(f"/mcdev/mobile-mods/{quote(str(id), safe='')}/review-submissions/current", None, **kwargs)
|
|
1297
|
+
|
|
1298
|
+
def status(self, id: str, **kwargs: Any) -> Any:
|
|
1299
|
+
"""查询手机组件处理状态"""
|
|
1300
|
+
return self._get(f"/mcdev/mobile-mods/{quote(str(id), safe='')}/status", None, **kwargs)
|
|
1301
|
+
|
|
1302
|
+
def submit_review(self, id: str, payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
1303
|
+
"""提交手机组件审核"""
|
|
1304
|
+
return self._post(f"/mcdev/mobile-mods/{quote(str(id), safe='')}/review-submissions", payload, **kwargs)
|
|
1305
|
+
|
|
1306
|
+
def update(self, id: str, payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
1307
|
+
"""保存手机组件修改"""
|
|
1308
|
+
return self._patch(f"/mcdev/mobile-mods/{quote(str(id), safe='')}", payload, **kwargs)
|
|
1309
|
+
|
|
1310
|
+
def upload(self, payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
1311
|
+
"""上传手机组件素材"""
|
|
1312
|
+
payload = _MultipartBody(payload, ['file'])
|
|
1313
|
+
return self._post(f"/mcdev/mobile-mods/uploads", payload, **kwargs)
|
|
1314
|
+
|
|
1315
|
+
class OSSAPI(_BaseApi):
|
|
1316
|
+
def get_ze_content(self, fileName: str, query: Optional[QueryParams] = None, **kwargs: Any) -> Any:
|
|
1317
|
+
"""读取 ZE OSS 配置内容"""
|
|
1318
|
+
return self._get(f"/managed-objects/ze/content/{quote(str(fileName), safe='')}", query, **kwargs)
|
|
1319
|
+
|
|
1320
|
+
def get_zvs_reload_content(self, fileName: str, query: Optional[QueryParams] = None, **kwargs: Any) -> Any:
|
|
1321
|
+
"""读取 ZVS Reload OSS 配置内容"""
|
|
1322
|
+
return self._get(f"/managed-objects/zvs-reload/content/{quote(str(fileName), safe='')}", query, **kwargs)
|
|
1323
|
+
|
|
1324
|
+
def list_ze(self, **kwargs: Any) -> Any:
|
|
1325
|
+
"""列出 ZE OSS 配置"""
|
|
1326
|
+
return self._get(f"/managed-objects/ze", None, **kwargs)
|
|
1327
|
+
|
|
1328
|
+
def list_ze_versions(self, fileName: str, query: Optional[QueryParams] = None, **kwargs: Any) -> Any:
|
|
1329
|
+
"""查询 ZE OSS 配置版本"""
|
|
1330
|
+
return self._get(f"/managed-objects/ze/versions/{quote(str(fileName), safe='')}", query, **kwargs)
|
|
1331
|
+
|
|
1332
|
+
def list_zvs_reload(self, **kwargs: Any) -> Any:
|
|
1333
|
+
"""列出 ZVS Reload OSS 配置"""
|
|
1334
|
+
return self._get(f"/managed-objects/zvs-reload", None, **kwargs)
|
|
1335
|
+
|
|
1336
|
+
def list_zvs_reload_versions(self, fileName: str, query: Optional[QueryParams] = None, **kwargs: Any) -> Any:
|
|
1337
|
+
"""查询 ZVS Reload OSS 配置版本"""
|
|
1338
|
+
return self._get(f"/managed-objects/zvs-reload/versions/{quote(str(fileName), safe='')}", query, **kwargs)
|
|
1339
|
+
|
|
1340
|
+
def preview_ze_sync(self, mapKey: str, **kwargs: Any) -> Any:
|
|
1341
|
+
"""预览 bbdev Node-RED 到正式 OSS 的 ZE 同步"""
|
|
1342
|
+
return self._get(f"/managed-objects/ze/{quote(str(mapKey), safe='')}/sync-preview", None, **kwargs)
|
|
1343
|
+
|
|
1344
|
+
def publish_ze_from_bbdev(self, mapKey: str, payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
1345
|
+
"""从 bbdev Node-RED 发布 ZE 配置到正式 OSS"""
|
|
1346
|
+
return self._post(f"/managed-objects/ze/{quote(str(mapKey), safe='')}/publish-from-bbdev", payload, **kwargs)
|
|
1347
|
+
|
|
1348
|
+
def update_ze_content(self, fileName: str, payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
1349
|
+
"""更新 ZE OSS 配置内容"""
|
|
1350
|
+
return self._put(f"/managed-objects/ze/content/{quote(str(fileName), safe='')}", payload, **kwargs)
|
|
1351
|
+
|
|
1352
|
+
def update_zvs_reload_content(self, fileName: str, payload: Mapping[str, Any], **kwargs: Any) -> Any:
|
|
1353
|
+
"""更新 ZVS Reload OSS 配置内容"""
|
|
1354
|
+
return self._put(f"/managed-objects/zvs-reload/content/{quote(str(fileName), safe='')}", payload, **kwargs)
|
|
1355
|
+
|
|
1356
|
+
class ParkourAPI(_BaseApi):
|
|
1357
|
+
def get_level_detail(self, levelId: Union[int, float], **kwargs: Any) -> Any:
|
|
1358
|
+
"""获取跑酷关卡详情"""
|
|
1359
|
+
return self._get(f"/parkour/levels/{quote(str(levelId), safe='')}", None, **kwargs)
|
|
1360
|
+
|
|
1361
|
+
def get_level_leaderboard(self, levelId: Union[int, float], query: Optional[QueryParams] = None, **kwargs: Any) -> Any:
|
|
1362
|
+
"""获取跑酷关卡排行榜"""
|
|
1363
|
+
return self._get(f"/parkour/levels/{quote(str(levelId), safe='')}/leaderboard", query, **kwargs)
|
|
1364
|
+
|
|
1365
|
+
def get_levels(self, query: Optional[QueryParams] = None, **kwargs: Any) -> Any:
|
|
1366
|
+
"""分页查询跑酷关卡"""
|
|
1367
|
+
return self._get(f"/parkour/levels", query, **kwargs)
|
|
1368
|
+
|
|
1369
|
+
def get_tracks(self, **kwargs: Any) -> Any:
|
|
1370
|
+
"""获取跑酷赛道列表"""
|
|
1371
|
+
return self._get(f"/parkour/tracks", None, **kwargs)
|
|
1372
|
+
|
|
891
1373
|
class PlayerAPI(_BaseApi):
|
|
892
1374
|
def __init__(self, http: _HttpClient) -> None:
|
|
893
1375
|
super().__init__(http)
|
|
894
1376
|
self.entitlement = PlayerEntitlementAPI(http)
|
|
895
1377
|
self.leaderboard = PlayerLeaderboardAPI(http)
|
|
1378
|
+
self.parkour = PlayerParkourAPI(http)
|
|
896
1379
|
self.rank_score = PlayerRankScoreAPI(http)
|
|
897
1380
|
self.score = PlayerScoreAPI(http)
|
|
898
1381
|
self.source_account = PlayerSourceAccountAPI(http)
|
|
@@ -915,7 +1398,7 @@ class PlayerAPI(_BaseApi):
|
|
|
915
1398
|
return self._get(f"/players/{quote(str(ecid), safe='')}/farm/freshness-batches", query, **kwargs)
|
|
916
1399
|
|
|
917
1400
|
def get_farm_overview(self, ecid: str, query: Optional[QueryParams] = None, **kwargs: Any) -> Any:
|
|
918
|
-
"""查询 EC
|
|
1401
|
+
"""查询 EC 农场总览(S1 与 S2 核心状态)"""
|
|
919
1402
|
return self._get(f"/players/{quote(str(ecid), safe='')}/farm/overview", query, **kwargs)
|
|
920
1403
|
|
|
921
1404
|
def get_farm_summary(self, ecid: str, query: Optional[QueryParams] = None, **kwargs: Any) -> Any:
|
|
@@ -970,6 +1453,10 @@ class PlayerAPI(_BaseApi):
|
|
|
970
1453
|
"""分页查询玩家邀请记录"""
|
|
971
1454
|
return self._get(f"/players/{quote(str(ecid), safe='')}/referrals", query, **kwargs)
|
|
972
1455
|
|
|
1456
|
+
def resolve(self, nickid: str, **kwargs: Any) -> Any:
|
|
1457
|
+
"""解析举报匿名身份"""
|
|
1458
|
+
return self._get(f"/admin/nickname-sessions/{quote(str(nickid), safe='')}", None, **kwargs)
|
|
1459
|
+
|
|
973
1460
|
def search(self, query: Optional[QueryParams] = None, **kwargs: Any) -> Any:
|
|
974
1461
|
"""查询玩家搜索命中列表"""
|
|
975
1462
|
return self._get(f"/players", query, **kwargs)
|
|
@@ -988,6 +1475,19 @@ class PlayerLeaderboardAPI(_BaseApi):
|
|
|
988
1475
|
"""批量查询排行榜数据"""
|
|
989
1476
|
return self._get(f"/leaderboards/scores", query, **kwargs)
|
|
990
1477
|
|
|
1478
|
+
class PlayerParkourAPI(_BaseApi):
|
|
1479
|
+
def get_recent_scores(self, ecid: str, query: Optional[QueryParams] = None, **kwargs: Any) -> Any:
|
|
1480
|
+
"""获取玩家最近的跑酷成绩"""
|
|
1481
|
+
return self._get(f"/players/{quote(str(ecid), safe='')}/parkour/recent-scores", query, **kwargs)
|
|
1482
|
+
|
|
1483
|
+
def get_summary(self, ecid: str, **kwargs: Any) -> Any:
|
|
1484
|
+
"""获取玩家跑酷总览"""
|
|
1485
|
+
return self._get(f"/players/{quote(str(ecid), safe='')}/parkour/summary", None, **kwargs)
|
|
1486
|
+
|
|
1487
|
+
def get_track_progress(self, ecid: str, trackKey: str, query: Optional[QueryParams] = None, **kwargs: Any) -> Any:
|
|
1488
|
+
"""获取玩家单条赛道的逐关进度"""
|
|
1489
|
+
return self._get(f"/players/{quote(str(ecid), safe='')}/parkour/tracks/{quote(str(trackKey), safe='')}", query, **kwargs)
|
|
1490
|
+
|
|
991
1491
|
class PlayerRankScoreAPI(_BaseApi):
|
|
992
1492
|
def get_history(self, ecid: str, query: Optional[QueryParams] = None, **kwargs: Any) -> Any:
|
|
993
1493
|
"""查询玩家历史赛季段位数据"""
|
|
@@ -1389,11 +1889,17 @@ class ECAPIClient:
|
|
|
1389
1889
|
) -> None:
|
|
1390
1890
|
self._http = _HttpClient(base_url, auth, timeout_seconds, default_headers, auth_provider)
|
|
1391
1891
|
self.admin = AdminAPI(self._http)
|
|
1892
|
+
self.announcements = AnnouncementsAPI(self._http)
|
|
1392
1893
|
self.audit = AuditAPI(self._http)
|
|
1393
1894
|
self.auth = AuthAPI(self._http)
|
|
1895
|
+
self.catalog = CatalogAPI(self._http)
|
|
1394
1896
|
self.game_log = GameLogAPI(self._http)
|
|
1395
1897
|
self.homeland = EchoMelandAPI(self._http)
|
|
1396
1898
|
self.log = LogAPI(self._http)
|
|
1899
|
+
self.lottery = LotteryAPI(self._http)
|
|
1900
|
+
self.minecraft_developer = MinecraftDeveloperAPI(self._http)
|
|
1901
|
+
self.oss = OSSAPI(self._http)
|
|
1902
|
+
self.parkour = ParkourAPI(self._http)
|
|
1397
1903
|
self.pit2 = PIT2API(self._http)
|
|
1398
1904
|
self.player = PlayerAPI(self._http)
|
|
1399
1905
|
self.replay = ReplayAPI(self._http)
|