feat: support AntSword shell generate (#34)

This commit is contained in:
ReaJason
2025-02-19 00:04:29 +08:00
parent e71f980991
commit 583abbf9ba
98 changed files with 2860 additions and 152 deletions
+69 -32
View File
@@ -136,7 +136,7 @@ export function MainConfigCard({
name="server"
render={({ field }) => (
<FormItem className="space-y-1">
<FormLabel>{t("mainConfig.server")}</FormLabel>
<FormLabel className="h-6 flex items-center">{t("mainConfig.server")}</FormLabel>
<Select
onValueChange={(v) => {
field.onChange(v);
@@ -176,10 +176,10 @@ export function MainConfigCard({
control={form.control}
name="targetJdkVersion"
render={({ field }) => (
<FormItem className="flex flex-col mt-1">
<Label className="flex items-center">
<FormItem className="space-y-1">
<FormLabel className="h-6 flex items-center gap-1">
{t("mainConfig.jre")} {t("optional")} <JreTip />
</Label>
</FormLabel>
<Select
onValueChange={(v) => {
if (Number.parseInt(v) >= 53) {
@@ -255,7 +255,7 @@ export function MainConfigCard({
<BehinderTabContent form={form} shellTypes={shellTypes} />
<GodzillaTabContent form={form} shellTypes={shellTypes} />
<CommandTabContent form={form} shellTypes={shellTypes} />
<AntSwordTabContent />
<AntSwordTabContent form={form} shellTypes={shellTypes} />
<Suo5TabContent form={form} shellTypes={shellTypes} />
<NeoreGeorgTabContent />
</Tabs>
@@ -272,7 +272,7 @@ function ShellTypeFormField({ form, shellTypes }: { form: UseFormReturn<FormSche
name="shellType"
render={({ field }) => (
<FormItem className="space-y-1">
<FormLabel>{t("mainConfig.shellMountType")}</FormLabel>
<FormLabel className="h-6 flex items-center">{t("mainConfig.shellMountType")}</FormLabel>
<Select onValueChange={field.onChange} value={field.value}>
<FormControl>
<SelectTrigger className="h-8">
@@ -306,10 +306,10 @@ function UrlPatternFormField({ form }: { form: UseFormReturn<FormSchema> }) {
control={form.control}
name="urlPattern"
render={({ field }) => (
<FormItem className="flex flex-col mt-1">
<Label className="flex items-center">
<FormItem className="space-y-1">
<FormLabel className="h-6 flex items-center gap-1">
{t("mainConfig.urlPattern")} <UrlPatternTip />
</Label>
</FormLabel>
<Input {...field} placeholder={t("placeholders.input")} className="h-8" />
</FormItem>
)}
@@ -327,7 +327,7 @@ function OptionalClassFormField({ form }: { form: UseFormReturn<FormSchema> }) {
name="shellClassName"
render={({ field }) => (
<FormItem className="space-y-1">
<FormLabel>
<FormLabel className="h-6 flex items-center gap-1">
{t("mainConfig.shellClassName")} {t("optional")}
</FormLabel>
<Input id="shellClassName" {...field} placeholder={t("placeholders.input")} className="h-8" />
@@ -339,7 +339,7 @@ function OptionalClassFormField({ form }: { form: UseFormReturn<FormSchema> }) {
name="injectorClassName"
render={({ field }) => (
<FormItem className="space-y-1">
<FormLabel>
<FormLabel className="h-6 flex items-center gap-1">
{t("mainConfig.injectorClassName")} {t("optional")}
</FormLabel>
<Input id="injectorClassName" {...field} placeholder={t("placeholders.input")} className="h-8" />
@@ -366,8 +366,8 @@ function BehinderTabContent({ form, shellTypes }: { form: UseFormReturn<FormSche
name="behinderPass"
render={({ field }) => (
<FormItem className="space-y-1">
<FormLabel>{t("shellToolConfig.behinderPass")}</FormLabel>
<Input {...field} placeholder={t("shellToolConfig.pass")} className="h-8" />
<FormLabel className="h-6 flex items-center gap-1">{t("shellToolConfig.behinderPass")}</FormLabel>
<Input {...field} placeholder={t("placeholders.input")} className="h-8" />
</FormItem>
)}
/>
@@ -377,7 +377,7 @@ function BehinderTabContent({ form, shellTypes }: { form: UseFormReturn<FormSche
name="headerName"
render={({ field }) => (
<FormItem className="space-y-1">
<FormLabel>{t("shellToolConfig.headerName")}</FormLabel>
<FormLabel className="h-6 flex items-center gap-1">{t("shellToolConfig.headerName")}</FormLabel>
<Input {...field} placeholder={t("shellToolConfig.headerName")} className="h-8" />
</FormItem>
)}
@@ -387,7 +387,7 @@ function BehinderTabContent({ form, shellTypes }: { form: UseFormReturn<FormSche
name="headerValue"
render={({ field }) => (
<FormItem className="space-y-1">
<FormLabel>{t("shellToolConfig.headerValue")}</FormLabel>
<FormLabel className="h-6 flex items-center gap-1">{t("shellToolConfig.headerValue")}</FormLabel>
<Input {...field} placeholder={t("shellToolConfig.headerValue")} className="h-8" />
</FormItem>
)}
@@ -418,7 +418,7 @@ function GodzillaTabContent({ form, shellTypes }: { form: UseFormReturn<FormSche
name="godzillaPass"
render={({ field }) => (
<FormItem className="space-y-1">
<FormLabel>{t("shellToolConfig.pass")}</FormLabel>
<FormLabel className="h-6 flex items-center gap-1">{t("shellToolConfig.pass")}</FormLabel>
<Input {...field} placeholder={t("shellToolConfig.pass")} className="h-8" />
</FormItem>
)}
@@ -428,7 +428,7 @@ function GodzillaTabContent({ form, shellTypes }: { form: UseFormReturn<FormSche
name="godzillaKey"
render={({ field }) => (
<FormItem className="space-y-1">
<FormLabel>{t("shellToolConfig.key")}</FormLabel>
<FormLabel className="h-6 flex items-center gap-1">{t("shellToolConfig.key")}</FormLabel>
<Input {...field} placeholder={t("shellToolConfig.key")} className="h-8" />
</FormItem>
)}
@@ -438,7 +438,7 @@ function GodzillaTabContent({ form, shellTypes }: { form: UseFormReturn<FormSche
name="headerName"
render={({ field }) => (
<FormItem className="space-y-1">
<FormLabel>{t("shellToolConfig.headerName")}</FormLabel>
<FormLabel className="h-6 flex items-center gap-1">{t("shellToolConfig.headerName")}</FormLabel>
<Input {...field} placeholder={t("shellToolConfig.headerName")} className="h-8" />
</FormItem>
)}
@@ -448,7 +448,7 @@ function GodzillaTabContent({ form, shellTypes }: { form: UseFormReturn<FormSche
name="headerValue"
render={({ field }) => (
<FormItem className="space-y-1">
<FormLabel>{t("shellToolConfig.headerValue")}</FormLabel>
<FormLabel className="h-6 flex items-center gap-1">{t("shellToolConfig.headerValue")}</FormLabel>
<Input {...field} placeholder={t("shellToolConfig.headerValue")} className="h-8" />
</FormItem>
)}
@@ -478,7 +478,7 @@ function CommandTabContent({ form, shellTypes }: { form: UseFormReturn<FormSchem
name="commandParamName"
render={({ field }) => (
<FormItem className="space-y-1">
<FormLabel>{t("shellToolConfig.paramName")}</FormLabel>
<FormLabel className="h-6 flex items-center gap-1">{t("shellToolConfig.paramName")}</FormLabel>
<FormControl>
<Input {...field} placeholder={t("shellToolConfig.paramName")} className="h-8" />
</FormControl>
@@ -493,17 +493,54 @@ function CommandTabContent({ form, shellTypes }: { form: UseFormReturn<FormSchem
);
}
function AntSwordTabContent() {
function AntSwordTabContent({ form, shellTypes }: { form: UseFormReturn<FormSchema>; shellTypes: Array<string> }) {
const { t } = useTranslation();
return (
<TabsContent value="AntSword">
<Card>
<CardContent className="space-y-2 mt-4">
<div className="flex items-center justify-center">
<span className="text-gray-500">WIP</span>
</div>
</CardContent>
</Card>
</TabsContent>
<FormProvider {...form}>
<TabsContent value="AntSword">
<Card>
<CardContent className="space-y-2 mt-4">
<div className="grid grid-cols-2 gap-2">
<ShellTypeFormField form={form} shellTypes={shellTypes} />
<UrlPatternFormField form={form} />
</div>
<FormField
control={form.control}
name="antSwordPass"
render={({ field }) => (
<FormItem className="space-y-1">
<FormLabel className="h-6 flex items-center gap-1">{t("shellToolConfig.antSwordPass")}</FormLabel>
<Input {...field} placeholder={t("placeholders.input")} className="h-8" />
</FormItem>
)}
/>
<div className="grid grid-cols-2 gap-2">
<FormField
control={form.control}
name="headerName"
render={({ field }) => (
<FormItem className="space-y-1">
<FormLabel className="h-6 flex items-center gap-1">{t("shellToolConfig.headerName")}</FormLabel>
<Input {...field} placeholder={t("shellToolConfig.headerName")} className="h-8" />
</FormItem>
)}
/>
<FormField
control={form.control}
name="headerValue"
render={({ field }) => (
<FormItem className="space-y-1">
<FormLabel className="h-6 flex items-center gap-1">{t("shellToolConfig.headerValue")}</FormLabel>
<Input {...field} placeholder={t("shellToolConfig.headerValue")} className="h-8" />
</FormItem>
)}
/>
</div>
<OptionalClassFormField form={form} />
</CardContent>
</Card>
</TabsContent>
</FormProvider>
);
}
@@ -524,7 +561,7 @@ function Suo5TabContent({ form, shellTypes }: { form: UseFormReturn<FormSchema>;
name="headerName"
render={({ field }) => (
<FormItem className="space-y-1">
<FormLabel>{t("shellToolConfig.headerName")}</FormLabel>
<FormLabel className="h-6 flex items-center gap-1">{t("shellToolConfig.headerName")}</FormLabel>
<Input {...field} placeholder={t("shellToolConfig.headerName")} className="h-8" />
</FormItem>
)}
@@ -534,7 +571,7 @@ function Suo5TabContent({ form, shellTypes }: { form: UseFormReturn<FormSchema>;
name="headerValue"
render={({ field }) => (
<FormItem className="space-y-1">
<FormLabel>{t("shellToolConfig.headerValue")}</FormLabel>
<FormLabel className="h-6 flex items-center gap-1">{t("shellToolConfig.headerValue")}</FormLabel>
<Input {...field} placeholder={t("shellToolConfig.headerValue")} className="h-8" />
</FormItem>
)}
+1 -1
View File
@@ -67,7 +67,7 @@ export function PackageConfigCard({
name="packingMethod"
render={({ field }) => (
<FormItem className="space-y-3">
<FormLabel>{t("packageConfig.title")}</FormLabel>
<FormLabel className="h-6 flex items-center gap-1">{t("packageConfig.title")}</FormLabel>
<FormControl>
<RadioGroup onValueChange={field.onChange} value={field.value} className="grid grid-cols-3">
{options.map(({ name, value }) => (
+5 -1
View File
@@ -1,4 +1,5 @@
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card.tsx";
import { ScrollTextIcon } from "lucide-react";
import { useTranslation } from "react-i18next";
export function QuickUsage() {
@@ -6,7 +7,10 @@ export function QuickUsage() {
return (
<Card>
<CardHeader>
<CardTitle>{t("quickUsage.title")}</CardTitle>
<CardTitle className="text-md flex items-center gap-2">
<ScrollTextIcon className="h-5" />
<span>{t("quickUsage.title")}</span>
</CardTitle>
</CardHeader>
<CardContent>
<ol className="list-decimal list-inside space-y-4 text-sm">
+100 -85
View File
@@ -20,6 +20,7 @@ import { Separator } from "@/components/ui/separator.tsx";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs.tsx";
import { downloadBytes } from "@/lib/utils.ts";
import {
AntSwordShellToolConfig,
BehinderShellToolConfig,
CommandShellToolConfig,
GenerateResult,
@@ -27,7 +28,7 @@ import {
Suo5ShellToolConfig,
} from "@/types/shell.ts";
import { TFunction } from "i18next";
import { CircleHelpIcon, TriangleAlertIcon } from "lucide-react";
import { CircleHelpIcon, TicketCheckIcon, TriangleAlertIcon } from "lucide-react";
import { Fragment, useState } from "react";
import { useTranslation } from "react-i18next";
import { toast } from "sonner";
@@ -143,7 +144,10 @@ function BasicInfo({ generateResult }: { generateResult?: GenerateResult }) {
<Card>
<CardHeader>
<CardTitle className="flex items-center justify-between">
{t("generateResult.basicInfo")}
<div className="text-md flex items-center gap-2">
<TicketCheckIcon className="h-5" />
<span>{t("generateResult.basicInfo")}</span>
</div>
<FeedbackAlert />
</CardTitle>
</CardHeader>
@@ -216,6 +220,20 @@ function BasicInfo({ generateResult }: { generateResult?: GenerateResult }) {
/>
</Fragment>
)}
{generateResult?.shellConfig.shellTool === "AntSword" && (
<Fragment>
<CopyableField
label={t("shellToolConfig.antSwordPass")}
text={(generateResult?.shellToolConfig as AntSwordShellToolConfig).pass}
value={(generateResult?.shellToolConfig as AntSwordShellToolConfig).pass}
/>
<CopyableField
label={t("shellToolConfig.httpHeader")}
text={`${(generateResult?.shellToolConfig as AntSwordShellToolConfig).headerName}: ${(generateResult?.shellToolConfig as AntSwordShellToolConfig).headerValue}`}
value={`${(generateResult?.shellToolConfig as AntSwordShellToolConfig).headerName}: ${(generateResult?.shellToolConfig as AntSwordShellToolConfig).headerValue}`}
/>
</Fragment>
)}
<CopyableField
label={t("mainConfig.injectorClassName")}
value={generateResult?.injectorClassName}
@@ -337,89 +355,86 @@ export function ShellResult({
generateResult?: GenerateResult;
}) {
const { t } = useTranslation();
if (!generateResult) {
return <QuickUsage />;
}
return (
<Fragment>
{generateResult ? (
<Tabs defaultValue="packResult">
<TabsList className="grid w-full grid-cols-3">
<TabsTrigger value="packResult">{t("generateResult.title1")}</TabsTrigger>
<TabsTrigger value="shell">{t("generateResult.title2")}</TabsTrigger>
<TabsTrigger value="injector">{t("generateResult.title3")}</TabsTrigger>
</TabsList>
<TabsContent value="packResult" className="my-4">
<div className="mb-4">
<BasicInfo generateResult={generateResult} />
</div>
{renderResultComponent(packResult, allPackResults, packMethod, t, generateResult)}
</TabsContent>
<TabsContent value="shell" className="mt-4">
<Alert>
<TriangleAlertIcon className="h-4 w-4" />
<AlertTitle>Warning</AlertTitle>
<AlertDescription>{t("tips.decompileTip")}</AlertDescription>
</Alert>
<div className="gap-4 my-2 flex items-center justify-end">
<Button
size="sm"
variant="outline"
className="w-28"
type="button"
onClick={() => {
if (!generateResult?.shellBytesBase64Str) {
toast.warning(t("tips.shellBytesEmpty"));
return;
}
downloadBytes(generateResult?.shellBytesBase64Str, generateResult?.shellClassName);
}}
>
{t("download")} Class
</Button>
</div>
<CodeViewer
showLineNumbers={false}
header={<div className="text-xs">{generateResult?.shellClassName}</div>}
wrapLongLines={true}
height={600}
code={generateResult?.shellBytesBase64Str ?? ""}
language="text"
/>
</TabsContent>
<TabsContent value="injector" className="mt-4">
<Alert>
<TriangleAlertIcon className="h-4 w-4" />
<AlertTitle>Warning</AlertTitle>
<AlertDescription>{t("tips.decompileTip")}</AlertDescription>
</Alert>
<div className="gap-4 my-2 flex items-center justify-end">
<Button
size="sm"
className="w-28"
variant="outline"
type="button"
onClick={() => {
if (!generateResult?.injectorBytesBase64Str) {
toast.warning(t("tips.shellBytesEmpty"));
return;
}
downloadBytes(generateResult?.injectorBytesBase64Str, generateResult?.injectorClassName);
}}
>
{t("download")} Class
</Button>
</div>
<CodeViewer
showLineNumbers={false}
wrapLongLines={true}
header={<div className="text-xs">{generateResult?.injectorClassName}</div>}
height={600}
code={generateResult?.injectorBytesBase64Str ?? ""}
language="text"
/>
</TabsContent>
</Tabs>
) : (
<QuickUsage />
)}
</Fragment>
<Tabs defaultValue="packResult">
<TabsList className="grid w-full grid-cols-3">
<TabsTrigger value="packResult">{t("generateResult.title1")}</TabsTrigger>
<TabsTrigger value="shell">{t("generateResult.title2")}</TabsTrigger>
<TabsTrigger value="injector">{t("generateResult.title3")}</TabsTrigger>
</TabsList>
<TabsContent value="packResult" className="my-4">
<div className="mb-4">
<BasicInfo generateResult={generateResult} />
</div>
{renderResultComponent(packResult, allPackResults, packMethod, t, generateResult)}
</TabsContent>
<TabsContent value="shell" className="mt-4">
<Alert>
<TriangleAlertIcon className="h-4 w-4" />
<AlertTitle>Warning</AlertTitle>
<AlertDescription>{t("tips.decompileTip")}</AlertDescription>
</Alert>
<div className="gap-4 my-2 flex items-center justify-end">
<Button
size="sm"
variant="outline"
className="w-28"
type="button"
onClick={() => {
if (!generateResult?.shellBytesBase64Str) {
toast.warning(t("tips.shellBytesEmpty"));
return;
}
downloadBytes(generateResult?.shellBytesBase64Str, generateResult?.shellClassName);
}}
>
{t("download")} Class
</Button>
</div>
<CodeViewer
showLineNumbers={false}
header={<div className="text-xs">{generateResult?.shellClassName}</div>}
wrapLongLines={true}
height={600}
code={generateResult?.shellBytesBase64Str ?? ""}
language="text"
/>
</TabsContent>
<TabsContent value="injector" className="mt-4">
<Alert>
<TriangleAlertIcon className="h-4 w-4" />
<AlertTitle>Warning</AlertTitle>
<AlertDescription>{t("tips.decompileTip")}</AlertDescription>
</Alert>
<div className="gap-4 my-2 flex items-center justify-end">
<Button
size="sm"
className="w-28"
variant="outline"
type="button"
onClick={() => {
if (!generateResult?.injectorBytesBase64Str) {
toast.warning(t("tips.shellBytesEmpty"));
return;
}
downloadBytes(generateResult?.injectorBytesBase64Str, generateResult?.injectorClassName);
}}
>
{t("download")} Class
</Button>
</div>
<CodeViewer
showLineNumbers={false}
wrapLongLines={true}
header={<div className="text-xs">{generateResult?.injectorClassName}</div>}
height={600}
code={generateResult?.injectorBytesBase64Str ?? ""}
language="text"
/>
</TabsContent>
</Tabs>
);
}