mirror of
https://github.com/neoarz/Syntrel.git
synced 2025-12-25 11:40:12 +01:00
Merge pull request #3 from neoarz/readme+idevice
This commit is contained in:
36
README.md
36
README.md
@@ -8,13 +8,41 @@
|
|||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
> [!NOTE]
|
<div align="center">
|
||||||
> **New Project**
|
|
||||||
>
|
**All in one discord bot for helping with [SideStore](https://discord.gg/3DwCwpBHfv), [idevice](https://discord.gg/ZnNcrRT3M8), and more.**
|
||||||
> This project is still in the making!!! I would appreciate if you gave this repo a star, that would mean a lot to me!
|
|
||||||
|
</div>
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> This bot is heavily customized and may not be a good starting point template wise. But if you wanna use this bot, or maybe add to your own server, download it by clicking the button below.
|
||||||
|
|
||||||
|
### Download
|
||||||
|
|
||||||
|
<div align="left">
|
||||||
|
<a href="https://discord.com/oauth2/authorize?client_id=1376728824108286034" target="_blank" rel="noopener noreferrer">
|
||||||
|
<img src="assets/download.png" alt="Download" style="width: 300px; height: auto;">
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
### Commands
|
||||||
|
|
||||||
|
| Command group | Subcommands |
|
||||||
|
| --- | --- |
|
||||||
|
| owner | `sync`, `cog_management`, `shutdown`, `say`, `invite` |
|
||||||
|
| general | `help`, `botinfo`, `serverinfo`, `ping`, `feedback`, `uptime` |
|
||||||
|
| fun | `randomfact`, `coinflip`, `rps`, `8ball`, `minesweeper` |
|
||||||
|
| moderation | `kick`, `ban`, `nick`, `purge`, `hackban`, `warnings`, `archive` |
|
||||||
|
| sidestore | `sidestore`, `refresh`, `code`, `crash`, `pairing`, `server`, `half`, `sparse`, `afc`, `udid` |
|
||||||
|
| idevice | `idevice`, `noapps`, `errorcode` |
|
||||||
|
| miscellaneous | `keanu`, `labubu` |
|
||||||
|
|
||||||
|
|
||||||
|
### Contributing
|
||||||
|
Contributions are welcome. See `CONTRIBUTING.md` for guidelines.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
Dual licensed project, see [LICENSE](LICENSE) file for detailed attribution information
|
Dual licensed project, see [LICENSE](LICENSE) file for detailed attribution information
|
||||||
|
|||||||
22
TODO.md
22
TODO.md
@@ -1,18 +1,18 @@
|
|||||||
# Todo List for Syntrel
|
# Todo List for Syntrel
|
||||||
|
|
||||||
[ ] Finish [idevice commands](https://github.com/jkcoxson/idevice/blob/master/idevice/src/lib.rs#L522)
|
- [x] Finish [idevice commands](https://github.com/jkcoxson/idevice/blob/master/idevice/src/lib.rs#L522)
|
||||||
> [X] Add /idevice command
|
- [x] Add /idevice command
|
||||||
>
|
- [x] Add /no apps command
|
||||||
> [X] Add /no apps command
|
- [x] Add rest of the errors yikes
|
||||||
>
|
|
||||||
> [ ] Add rest of the errors yikes
|
|
||||||
|
|
||||||
[ ] Add unit tests
|
- [ ] Add unit tests
|
||||||
|
|
||||||
[ ] Add documentation to readme
|
- [ ] Add documentation to readme
|
||||||
|
|
||||||
[ ] Clean tag system from [tags branch](https://github.com/neoarz/Syntrel/tree/tags) (make sure db is persistent)
|
- [ ] Finish CONTRIBUTING.md
|
||||||
|
|
||||||
[X] Fix logging and add graceful shutdown
|
- [ ] Clean tag system from [tags branch](https://github.com/neoarz/Syntrel/tree/tags) (make sure db is persistent)
|
||||||
|
|
||||||
[X] Add uptime checker for the bot iself
|
- [x] Fix logging and add graceful shutdown
|
||||||
|
|
||||||
|
- [x] Add uptime checker for the bot iself
|
||||||
|
|||||||
BIN
assets/download.png
Normal file
BIN
assets/download.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 985 KiB |
74
cogs/idevice/error_codes.py
Normal file
74
cogs/idevice/error_codes.py
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
import json
|
||||||
|
import os
|
||||||
|
import discord
|
||||||
|
from discord import app_commands
|
||||||
|
from discord.ext import commands
|
||||||
|
|
||||||
|
|
||||||
|
class ErrorCodes(commands.Cog, name="errorcodes"):
|
||||||
|
def __init__(self, bot) -> None:
|
||||||
|
self.bot = bot
|
||||||
|
self.errors = self.load_errors()
|
||||||
|
self.key_to_data = {error['name']: (error['description'], error['code']) for error in self.errors}
|
||||||
|
self.code_to_key = {error['code']: error['name'] for error in self.errors}
|
||||||
|
|
||||||
|
def load_errors(self):
|
||||||
|
json_path = os.path.join(os.path.dirname(__file__), 'errorcodes.json')
|
||||||
|
try:
|
||||||
|
with open(json_path, 'r', encoding='utf-8') as f:
|
||||||
|
return json.load(f)
|
||||||
|
except FileNotFoundError:
|
||||||
|
self.bot.logger.error(f"Error codes JSON file not found: {json_path}")
|
||||||
|
return []
|
||||||
|
except json.JSONDecodeError as e:
|
||||||
|
self.bot.logger.error(f"Error parsing error codes JSON: {e}")
|
||||||
|
return []
|
||||||
|
|
||||||
|
async def errorcode_autocomplete(self, interaction: discord.Interaction, current: str):
|
||||||
|
current_lower = current.lower()
|
||||||
|
items = []
|
||||||
|
for key, (title, code) in self.key_to_data.items():
|
||||||
|
if not current or current_lower in key.lower() or current_lower in title.lower() or current_lower in str(code):
|
||||||
|
items.append(app_commands.Choice(name=f"{key} » {title} ({code})", value=key))
|
||||||
|
if len(items) >= 25:
|
||||||
|
break
|
||||||
|
return items
|
||||||
|
|
||||||
|
@app_commands.command(name="errorcode", description="Look up an idevice error code by name or number")
|
||||||
|
@app_commands.describe(name="Start typing to search all error names and codes")
|
||||||
|
@app_commands.autocomplete(name=errorcode_autocomplete)
|
||||||
|
async def errorcode(self, interaction: discord.Interaction, name: str):
|
||||||
|
key = name
|
||||||
|
if key not in self.key_to_data:
|
||||||
|
try:
|
||||||
|
num = int(name)
|
||||||
|
key = self.code_to_key.get(num)
|
||||||
|
except ValueError:
|
||||||
|
key = None
|
||||||
|
if key is None or key not in self.key_to_data:
|
||||||
|
await interaction.response.send_message("Error not found.", ephemeral=True)
|
||||||
|
return
|
||||||
|
|
||||||
|
title, code = self.key_to_data[key]
|
||||||
|
|
||||||
|
embed = discord.Embed(
|
||||||
|
description=f"## Error Code: {code}\n\n**Name**: `{key}`\n**Description**: {title}",
|
||||||
|
color=0xfa8c4a,
|
||||||
|
)
|
||||||
|
embed.set_author(name="idevice", icon_url="https://yes.nighty.works/raw/snLMuO.png")
|
||||||
|
|
||||||
|
view = discord.ui.View()
|
||||||
|
view.add_item(discord.ui.Button(
|
||||||
|
label="Edit Command",
|
||||||
|
style=discord.ButtonStyle.secondary,
|
||||||
|
url="https://github.com/neoarz/Syntrel/blob/main/cogs/idevice/error_codes.py",
|
||||||
|
emoji="<:githubicon:1417717356846776340>"
|
||||||
|
))
|
||||||
|
|
||||||
|
await interaction.response.send_message(embed=embed, view=view)
|
||||||
|
|
||||||
|
async def setup(bot) -> None:
|
||||||
|
cog = ErrorCodes(bot)
|
||||||
|
await bot.add_cog(cog)
|
||||||
|
|
||||||
|
|
||||||
332
cogs/idevice/errorcodes.json
Normal file
332
cogs/idevice/errorcodes.json
Normal file
@@ -0,0 +1,332 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "socket",
|
||||||
|
"description": "device socket io failed",
|
||||||
|
"code": -1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pem_parse_failed",
|
||||||
|
"description": "PEM parse failed",
|
||||||
|
"code": -2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "rustls",
|
||||||
|
"description": "TLS error",
|
||||||
|
"code": -3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "tls_builder_failed",
|
||||||
|
"description": "TLS verifiction build failed",
|
||||||
|
"code": -4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "plist",
|
||||||
|
"description": "io on plist",
|
||||||
|
"code": -5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "utf8",
|
||||||
|
"description": "can't convert bytes to utf8",
|
||||||
|
"code": -6
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "unexpected_response",
|
||||||
|
"description": "unexpected response from device",
|
||||||
|
"code": -7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "get_prohibited",
|
||||||
|
"description": "this request was prohibited",
|
||||||
|
"code": -8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "session_inactive",
|
||||||
|
"description": "no SSL session is active",
|
||||||
|
"code": -9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "invalid_host_id",
|
||||||
|
"description": "device does not have pairing file",
|
||||||
|
"code": -10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "no_established_connection",
|
||||||
|
"description": "no established connection",
|
||||||
|
"code": -11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "heartbeat_sleepy_time",
|
||||||
|
"description": "device went to sleep",
|
||||||
|
"code": -12
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "heartbeat_timeout",
|
||||||
|
"description": "heartbeat timeout",
|
||||||
|
"code": -13
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "not_found",
|
||||||
|
"description": "not found",
|
||||||
|
"code": -14
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "service_not_found",
|
||||||
|
"description": "service not found",
|
||||||
|
"code": -15
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "cdtunnel_packet_too_short",
|
||||||
|
"description": "CDTunnel packet too short",
|
||||||
|
"code": -16
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "cdtunnel_packet_invalid_magic",
|
||||||
|
"description": "CDTunnel packet invalid magic",
|
||||||
|
"code": -17
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "packet_size_mismatch",
|
||||||
|
"description": "Proclaimed packet size does not match actual size",
|
||||||
|
"code": -18
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "json",
|
||||||
|
"description": "JSON serialization failed",
|
||||||
|
"code": -19
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "device_not_found",
|
||||||
|
"description": "device not found",
|
||||||
|
"code": -20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "device_locked",
|
||||||
|
"description": "device lockded",
|
||||||
|
"code": -21
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "usb_connection_refused",
|
||||||
|
"description": "device refused connection",
|
||||||
|
"code": -22
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "usb_bad_command",
|
||||||
|
"description": "bad command",
|
||||||
|
"code": -23
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "usb_bad_device",
|
||||||
|
"description": "bad device",
|
||||||
|
"code": -24
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "usb_bad_version",
|
||||||
|
"description": "usb bad version",
|
||||||
|
"code": -25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "bad_build_manifest",
|
||||||
|
"description": "bad build manifest",
|
||||||
|
"code": -26
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "image_not_mounted",
|
||||||
|
"description": "image not mounted",
|
||||||
|
"code": -27
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pairing_dialog_response_pending",
|
||||||
|
"description": "pairing trust dialog pending",
|
||||||
|
"code": -28
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "user_denied_pairing",
|
||||||
|
"description": "user denied pairing trust",
|
||||||
|
"code": -29
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "password_protected",
|
||||||
|
"description": "device is locked",
|
||||||
|
"code": -30
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "misagent_failure",
|
||||||
|
"description": "misagent operation failed",
|
||||||
|
"code": -31
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "installation_proxy_operation_failed",
|
||||||
|
"description": "installation proxy operation failed",
|
||||||
|
"code": -32
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "afc",
|
||||||
|
"description": "afc error",
|
||||||
|
"code": -33
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "unknown_afc_opcode",
|
||||||
|
"description": "unknown afc opcode",
|
||||||
|
"code": -34
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "invalid_afc_magic",
|
||||||
|
"description": "invalid afc magic",
|
||||||
|
"code": -35
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "afc_missing_attribute",
|
||||||
|
"description": "missing file attribute",
|
||||||
|
"code": -36
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "crash_report_mover_bad_response",
|
||||||
|
"description": "crash report mover sent the wrong response",
|
||||||
|
"code": -37
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "reqwest",
|
||||||
|
"description": "http reqwest error",
|
||||||
|
"code": -38
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "internal_error",
|
||||||
|
"description": "internal error",
|
||||||
|
"code": -39
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "unknown_frame",
|
||||||
|
"description": "unknown http frame type",
|
||||||
|
"code": -40
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "unknown_http_setting",
|
||||||
|
"description": "unknown http setting type",
|
||||||
|
"code": -41
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "uninitialized_stream_id",
|
||||||
|
"description": "Unintialized stream ID",
|
||||||
|
"code": -42
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "unknown_xpc_type",
|
||||||
|
"description": "unknown XPC type",
|
||||||
|
"code": -43
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "malformed_xpc",
|
||||||
|
"description": "malformed XPC message",
|
||||||
|
"code": -44
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "invalid_xpc_magic",
|
||||||
|
"description": "invalid XPC magic",
|
||||||
|
"code": -45
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "unexpected_xpc_version",
|
||||||
|
"description": "unexpected XPC version",
|
||||||
|
"code": -46
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "invalid_c_string",
|
||||||
|
"description": "invalid C string",
|
||||||
|
"code": -47
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "http_stream_reset",
|
||||||
|
"description": "stream reset",
|
||||||
|
"code": -48
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "http_go_away",
|
||||||
|
"description": "go away packet received",
|
||||||
|
"code": -49
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ns_keyed_archive_error",
|
||||||
|
"description": "NSKeyedArchive error",
|
||||||
|
"code": -50
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "unknown_aux_value_type",
|
||||||
|
"description": "Unknown aux value type",
|
||||||
|
"code": -51
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "unknown_channel",
|
||||||
|
"description": "unknown channel",
|
||||||
|
"code": -52
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "addr_parse_error",
|
||||||
|
"description": "cannot parse string as IpAddr",
|
||||||
|
"code": -53
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "disable_memory_limit_failed",
|
||||||
|
"description": "disable memory limit failed",
|
||||||
|
"code": -54
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "not_enough_bytes",
|
||||||
|
"description": "not enough bytes",
|
||||||
|
"code": -55
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "utf8_error",
|
||||||
|
"description": "failed to parse bytes as valid utf8",
|
||||||
|
"code": -56
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "invalid_argument",
|
||||||
|
"description": "invalid argument passed",
|
||||||
|
"code": -57
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "unknown_error_type",
|
||||||
|
"description": "unknown error returned from device",
|
||||||
|
"code": -59
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ffi_invalid_arg",
|
||||||
|
"description": "invalid arguments were passed",
|
||||||
|
"code": -60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ffi_invalid_string",
|
||||||
|
"description": "invalid string was passed",
|
||||||
|
"code": -61
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ffi_buffer_too_small",
|
||||||
|
"description": "buffer passed is too small",
|
||||||
|
"code": -62
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "unsupported_watch_key",
|
||||||
|
"description": "unsupported watch key",
|
||||||
|
"code": -63
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "malformed_command",
|
||||||
|
"description": "malformed command",
|
||||||
|
"code": -64
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "integer_overflow",
|
||||||
|
"description": "integer overflow",
|
||||||
|
"code": -65
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "canceled_by_user",
|
||||||
|
"description": "canceled by user",
|
||||||
|
"code": -66
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "malformed_package_archive",
|
||||||
|
"description": "malformed package archive",
|
||||||
|
"code": -67
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -2,6 +2,142 @@ import discord
|
|||||||
from discord import app_commands
|
from discord import app_commands
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from discord.ext.commands import Context
|
from discord.ext.commands import Context
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import math
|
||||||
|
|
||||||
|
|
||||||
|
def load_error_codes():
|
||||||
|
try:
|
||||||
|
json_path = os.path.join(os.path.dirname(__file__), 'errorcodes.json')
|
||||||
|
with open(json_path, 'r', encoding='utf-8') as f:
|
||||||
|
return json.load(f)
|
||||||
|
except FileNotFoundError:
|
||||||
|
return []
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
return []
|
||||||
|
|
||||||
|
|
||||||
|
class ErrorCodesBrowserView(discord.ui.View):
|
||||||
|
def __init__(self, items_per_page=9):
|
||||||
|
super().__init__(timeout=300)
|
||||||
|
self.error_codes = load_error_codes()
|
||||||
|
self.items_per_page = items_per_page
|
||||||
|
self.current_page = 0
|
||||||
|
self.max_pages = math.ceil(len(self.error_codes) / items_per_page) if self.error_codes else 1
|
||||||
|
self.update_buttons()
|
||||||
|
|
||||||
|
def update_buttons(self):
|
||||||
|
self.clear_items()
|
||||||
|
|
||||||
|
first_button = discord.ui.Button(
|
||||||
|
emoji="<:leftmax:1420240325770870905>",
|
||||||
|
style=discord.ButtonStyle.primary,
|
||||||
|
disabled=(self.current_page == 0)
|
||||||
|
)
|
||||||
|
first_button.callback = self.first_page
|
||||||
|
self.add_item(first_button)
|
||||||
|
|
||||||
|
prev_button = discord.ui.Button(
|
||||||
|
emoji="<:left:1420240344926126090>",
|
||||||
|
style=discord.ButtonStyle.primary,
|
||||||
|
disabled=(self.current_page == 0)
|
||||||
|
)
|
||||||
|
prev_button.callback = self.prev_page
|
||||||
|
self.add_item(prev_button)
|
||||||
|
|
||||||
|
stop_button = discord.ui.Button(
|
||||||
|
emoji="<:middle:1420240356087173160>",
|
||||||
|
style=discord.ButtonStyle.secondary
|
||||||
|
)
|
||||||
|
stop_button.callback = self.stop_interaction
|
||||||
|
self.add_item(stop_button)
|
||||||
|
|
||||||
|
next_button = discord.ui.Button(
|
||||||
|
emoji="<:right:1420240334100627456>",
|
||||||
|
style=discord.ButtonStyle.primary,
|
||||||
|
disabled=(self.current_page >= self.max_pages - 1)
|
||||||
|
)
|
||||||
|
next_button.callback = self.next_page
|
||||||
|
self.add_item(next_button)
|
||||||
|
|
||||||
|
last_button = discord.ui.Button(
|
||||||
|
emoji="<:rightmax:1420240368846372886>",
|
||||||
|
style=discord.ButtonStyle.primary,
|
||||||
|
disabled=(self.current_page >= self.max_pages - 1)
|
||||||
|
)
|
||||||
|
last_button.callback = self.last_page
|
||||||
|
self.add_item(last_button)
|
||||||
|
|
||||||
|
def create_embed(self):
|
||||||
|
if not self.error_codes:
|
||||||
|
embed = discord.Embed(
|
||||||
|
title="Error Codes",
|
||||||
|
description="No error codes found.",
|
||||||
|
color=0xfa8c4a
|
||||||
|
)
|
||||||
|
embed.set_author(name="idevice", icon_url="https://yes.nighty.works/raw/snLMuO.png")
|
||||||
|
embed.set_footer(text="Page 0 of 0")
|
||||||
|
return embed
|
||||||
|
|
||||||
|
embed = discord.Embed(
|
||||||
|
title="Error Codes",
|
||||||
|
color=0xfa8c4a
|
||||||
|
)
|
||||||
|
embed.set_author(name="idevice", icon_url="https://yes.nighty.works/raw/snLMuO.png")
|
||||||
|
|
||||||
|
start_idx = self.current_page * self.items_per_page
|
||||||
|
end_idx = min(start_idx + self.items_per_page, len(self.error_codes))
|
||||||
|
current_codes = self.error_codes[start_idx:end_idx]
|
||||||
|
|
||||||
|
for i, error in enumerate(current_codes):
|
||||||
|
field_value = f"**Code:** `{error.get('code', 'N/A')}`\n**Name:** `{error.get('name', 'Unknown')}`\n**Description:** {error.get('description', 'No description')}"
|
||||||
|
embed.add_field(
|
||||||
|
name="\u200b",
|
||||||
|
value=field_value,
|
||||||
|
inline=True
|
||||||
|
)
|
||||||
|
|
||||||
|
# Add empty fields to maintain 3x3 grid if needed
|
||||||
|
while len(current_codes) % 3 != 0:
|
||||||
|
embed.add_field(name="\u200b", value="\u200b", inline=True)
|
||||||
|
|
||||||
|
embed.set_footer(text=f"Page {self.current_page + 1} of {self.max_pages}")
|
||||||
|
|
||||||
|
return embed
|
||||||
|
|
||||||
|
async def first_page(self, interaction: discord.Interaction):
|
||||||
|
self.current_page = 0
|
||||||
|
self.update_buttons()
|
||||||
|
embed = self.create_embed()
|
||||||
|
await interaction.response.edit_message(embed=embed, view=self)
|
||||||
|
|
||||||
|
async def prev_page(self, interaction: discord.Interaction):
|
||||||
|
if self.current_page > 0:
|
||||||
|
self.current_page -= 1
|
||||||
|
self.update_buttons()
|
||||||
|
embed = self.create_embed()
|
||||||
|
await interaction.response.edit_message(embed=embed, view=self)
|
||||||
|
|
||||||
|
async def stop_interaction(self, interaction: discord.Interaction):
|
||||||
|
self.clear_items()
|
||||||
|
embed = self.create_embed()
|
||||||
|
embed.set_footer(text="Interaction stopped")
|
||||||
|
await interaction.response.edit_message(embed=embed, view=self)
|
||||||
|
self.stop()
|
||||||
|
|
||||||
|
async def next_page(self, interaction: discord.Interaction):
|
||||||
|
if self.current_page < self.max_pages - 1:
|
||||||
|
self.current_page += 1
|
||||||
|
self.update_buttons()
|
||||||
|
embed = self.create_embed()
|
||||||
|
await interaction.response.edit_message(embed=embed, view=self)
|
||||||
|
|
||||||
|
async def last_page(self, interaction: discord.Interaction):
|
||||||
|
self.current_page = self.max_pages - 1
|
||||||
|
self.update_buttons()
|
||||||
|
embed = self.create_embed()
|
||||||
|
await interaction.response.edit_message(embed=embed, view=self)
|
||||||
|
|
||||||
|
|
||||||
class ideviceSelect(discord.ui.Select):
|
class ideviceSelect(discord.ui.Select):
|
||||||
@@ -12,12 +148,34 @@ class ideviceSelect(discord.ui.Select):
|
|||||||
label="No Apps",
|
label="No Apps",
|
||||||
value="noapps",
|
value="noapps",
|
||||||
description="Help when apps aren't showing in installed apps view",
|
description="Help when apps aren't showing in installed apps view",
|
||||||
)
|
),
|
||||||
|
discord.SelectOption(
|
||||||
|
label="Error Codes",
|
||||||
|
value="errorcodes_ephemeral",
|
||||||
|
description="Browse idevice error codes",
|
||||||
|
),
|
||||||
]
|
]
|
||||||
super().__init__(placeholder="Choose an idevice command...", options=options)
|
super().__init__(placeholder="Choose an idevice command...", options=options)
|
||||||
|
|
||||||
async def callback(self, interaction: discord.Interaction):
|
async def callback(self, interaction: discord.Interaction):
|
||||||
command_name = self.values[0]
|
command_name = self.values[0]
|
||||||
|
|
||||||
|
if command_name == "errorcodes_ephemeral":
|
||||||
|
# Send success message first
|
||||||
|
embed = discord.Embed(
|
||||||
|
title="Command Executed",
|
||||||
|
description="Successfully executed `/errorcodes`",
|
||||||
|
color=0x00FF00
|
||||||
|
)
|
||||||
|
embed.set_author(name="idevice", icon_url="https://yes.nighty.works/raw/snLMuO.png")
|
||||||
|
await interaction.response.edit_message(embed=embed, view=None)
|
||||||
|
|
||||||
|
# Follow up with the error codes browser
|
||||||
|
view = ErrorCodesBrowserView()
|
||||||
|
embed = view.create_embed()
|
||||||
|
await interaction.followup.send(embed=embed, view=view, ephemeral=True)
|
||||||
|
return
|
||||||
|
|
||||||
command = self.bot.get_command(command_name)
|
command = self.bot.get_command(command_name)
|
||||||
|
|
||||||
if command:
|
if command:
|
||||||
|
|||||||
Reference in New Issue
Block a user