001package polaris.sdk.ui.samples; 002 003import polaris.sdk.ui.*; 004import polaris.sdk.ui.controls.*; 005import java.util.*; 006import static polaris.sdk.ui.samples.SceneSupport.*; 007 008/** ClickGUI-like game-client configuration. UI state only: no injection, game hooks or network. */ 009public final class ClientScene extends SceneSupport.AppScene { 010 public static final class Module { 011 public final String name,description;public final int category;public boolean enabled,hold; 012 public double strength=50,low=25,high=75;public int mode;public String shortcut=""; 013 Module(String n,String d,int c,boolean e){name=n;description=d;category=c;enabled=e;} 014 } 015 private final List<Module> modules=new ArrayList<Module>();private final List<ModuleTile> tiles=new ArrayList<ModuleTile>(); 016 private final ListBox categories=new ListBox("战斗","移动","视觉","世界","杂项"); 017 private final SearchField search=new SearchField();private final ComboSelect profile=new ComboSelect("默认演示","录制布局","全部关闭"); 018 private final Button save=new Button("保存快照");private final Label count=caption("");private final Panel grid=new Panel(),inspector=new Panel(); 019 private final ScrollPane modulesScroll=new ScrollPane();private final ModuleGrid content=new ModuleGrid(); 020 private final Label selectedName=title("HUD"),selectedNote=caption(""),strengthLabel=caption("参数强度 / 50"),rangeLabel=caption("区间 / 25 – 75"); 021 private final Switch enabled=new Switch("启用此模块");private final Slider strength=new Slider();private final RangeSlider range=new RangeSlider(); 022 private final ComboSelect mode=new ComboSelect("标准","平滑","自定义");private final KeyBindingField key=new KeyBindingField();private final CheckBox hold=new CheckBox("仅按住时启用"); 023 private final Button reset=new Button("重置当前参数"),restore=new Button("载入快照"); 024 private int category;private Module selected;private List<Snapshot> snapshot; 025 private static final class Snapshot {final boolean enabled,hold;final double strength,low,high;final int mode;final String shortcut;Snapshot(Module m){enabled=m.enabled;hold=m.hold;strength=m.strength;low=m.low;high=m.high;mode=m.mode;shortcut=m.shortcut;}void apply(Module m){m.enabled=enabled;m.hold=hold;m.strength=strength;m.low=low;m.high=high;m.mode=mode;m.shortcut=shortcut;}} 026 public ClientScene(){super("POLARIS / ClickGUI","外挂风格客户端面板 / 仅演示配置界面,不接入游戏或执行模块");id("scene.client"); 027 modules.add(new Module("KillAura","目标配置界面 · 无游戏逻辑",0,false));modules.add(new Module("Velocity","受击参数界面 · 无游戏逻辑",0,false));modules.add(new Module("AutoClicker","点击参数界面 · 不执行点击",0,false)); 028 modules.add(new Module("Sprint","疾跑选项界面",1,true));modules.add(new Module("Speed","移动选项界面",1,false));modules.add(new Module("Flight","飞行选项界面",1,false)); 029 modules.add(new Module("HUD","屏幕信息组件",2,true));modules.add(new Module("ESP","轮廓显示选项",2,false));modules.add(new Module("Fullbright","亮度选项界面",2,false)); 030 modules.add(new Module("Scaffold","方块放置选项",3,false));modules.add(new Module("AutoTool","工具选项界面",3,false));modules.add(new Module("ChestStealer","容器选项界面",3,false)); 031 modules.add(new Module("Notifications","消息与状态提示",4,true));modules.add(new Module("Theme","外观参数界面",4,true));modules.add(new Module("IRC","聊天配置界面 · 不联网",4,false)); 032 mount(this,search,"client.search");search.placeholder("搜索模块…");search.onChange(v->filter());mount(this,profile,"client.profile");profile.onChange(v->applyProfile(profile.selectedIndex()));mount(this,save,"client.save");save.onClick(v->{snapshot=new ArrayList<Snapshot>();for(Module m:modules)snapshot.add(new Snapshot(m));restore.enabled(true);notice(this,"配置快照已保存","仅保存在本次展示窗口中。");});mount(this,count,"client.count"); 033 mount(this,categories,"client.categories");categories.glass(false).padding(0).rowHeight(45).rowGap(8);categories.onSelection(i->{category=Math.max(0,i);filter();}); 034 mount(this,grid,"client.modules");mount(grid,modulesScroll,"client.moduleScroll");modulesScroll.glass(false).padding(0).layout(Panel.Layout.COLUMN);modulesScroll.add(content); 035 for(Module m:modules){ModuleTile t=new ModuleTile(m);tiles.add(t);content.add(t);} 036 mount(this,inspector,"client.inspector");mount(inspector,selectedName,"client.selected");mount(inspector,selectedNote,null);mount(inspector,enabled,"client.enabled"); 037 enabled.onChange(v->{if(selected!=null){selected.enabled=enabled.selected();refresh();}}); 038 strength.range(0,100).continuous();mount(inspector,strengthLabel,null);mount(inspector,strength,"client.strength");strength.onChange(v->{selected.strength=strength.value();refreshLabels();}); 039 range.range(0,100);mount(inspector,rangeLabel,null);mount(inspector,range,"client.range");range.onChange(v->{selected.low=range.low();selected.high=range.high();refreshLabels();}); 040 mount(inspector,mode,"client.mode");mode.onChange(v->{if(selected!=null)selected.mode=mode.selectedIndex();}); 041 mount(inspector,key,"client.key");key.onChange(v->{if(selected!=null)selected.shortcut=key.value();}); 042 mount(inspector,hold,"client.hold");hold.onChange(v->selected.hold=hold.selected()); 043 mount(inspector,reset,"client.reset");reset.onClick(v->{selected.strength=50;selected.low=25;selected.high=75;selected.mode=0;selected.shortcut="";selected.hold=false;selectModule(selected.name);}); 044 mount(inspector,restore,"client.restore");restore.enabled(false);restore.onClick(v->{if(snapshot!=null){for(int i=0;i<modules.size();i++)snapshot.get(i).apply(modules.get(i));selectModule(selected.name);refresh();}}); 045 categories.select(0);selectModule("KillAura");refresh(); 046 } 047 public List<Module> modules(){return Collections.unmodifiableList(modules);} 048 public Module selectedModule(){return selected;} 049 public int enabledCount(){int n=0;for(Module m:modules)if(m.enabled)n++;return n;} 050 public void selectModule(String name){for(Module m:modules)if(m.name.equals(name)){selected=m;selectedName.text(m.name);selectedNote.text(m.description);enabled.selected(m.enabled);strength.value(m.strength);range.values(m.low,m.high);mode.select(m.mode);key.value(m.shortcut);hold.selected(m.hold);refreshLabels();return;}throw new IllegalArgumentException(name);} 051 private void refreshLabels(){strengthLabel.text("参数强度 / "+Math.round(selected.strength));rangeLabel.text("区间 / "+Math.round(selected.low)+" – "+Math.round(selected.high));} 052 private void refresh(){for(ModuleTile tile:tiles)tile.toggle.selected(tile.model.enabled);count.text(enabledCount()+" / "+modules.size()+" 已启用 · 界面模拟");if(selected!=null)enabled.selected(selected.enabled);} 053 private void filter(){String query=search.value().trim().toLowerCase(Locale.ROOT);for(ModuleTile t:tiles)t.visible((query.isEmpty()?t.model.category==category:true)&&(t.model.name.toLowerCase(Locale.ROOT).contains(query)||t.model.description.contains(query)));} 054 private void applyProfile(int index){for(Module m:modules)m.enabled=index==0?(m.name.equals("HUD")||m.name.equals("Sprint")||m.name.equals("Theme")||m.name.equals("Notifications")):index==1?(m.category==2||m.name.equals("Notifications")):false;refresh();} 055 @Override public float preferredHeight(float width){return width<900?1060:630;} 056 @Override protected void layoutChildren(){header();boolean stacked=w<900;float inspectorWidth=stacked?w:270,side=132,main=stacked?w-side-GAP:w-side-inspectorWidth-2*GAP; 057 place(search,0,76,Math.max(120,w-346),36);place(profile,w-334,76,186,36);place(save,w-136,76,136,36); 058 place(categories,0,132,side,360);place(grid,side+GAP,132,main,414);place(modulesScroll,16,16,main-32,382);content.bounds(0,0,modulesScroll.contentWidth(),content.height()); 059 place(inspector,stacked?0:w-inspectorWidth,stacked?562:132,inspectorWidth,414);float iw=inspectorWidth; 060 place(selectedName,16,16,iw-32,28);place(selectedNote,16,49,iw-32,22);place(enabled,16,82,iw-32,32); 061 place(strengthLabel,16,128,iw-32,20);place(strength,16,153,iw-32,28);place(rangeLabel,16,193,iw-32,20);place(range,16,217,iw-32,28); 062 place(mode,16,257,iw-32,32);place(key,16,301,iw-32,32);place(hold,16,345,iw-32,27); 063 // Buttons sit below the inspector to preserve a consistent 16 px inset. 064 inspector.bounds(inspector.x(),inspector.y(),iw,458);place(reset,16,399,(iw-44)/2,36);place(restore,28+(iw-44)/2,399,(iw-44)/2,36); 065 float bottom=Math.max(grid.y()+grid.height(),inspector.y()+inspector.height());place(count,0,bottom+12,w,22);h=bottom+40; 066 } 067 private final class ModuleGrid extends Panel { 068 ModuleGrid(){glass(false);padding(0);clipChildren(false);} 069 @Override protected void layoutChildren(){int columns=w>=420?2:1,n=0;float each=(w-(columns-1)*GAP)/columns;for(ModuleTile t:tiles)if(t.visible()){place(t,(n%columns)*(each+GAP),(n/columns)*112,each,100);n++;}h=Math.max(1,((n+columns-1)/columns)*112);} 070 } 071 private final class ModuleTile extends Panel { 072 final Module model;final Switch toggle;final Label note;final Button settings=new Button("参数"); 073 ModuleTile(Module m){model=m;toggle=new Switch(m.name);toggle.selected(m.enabled);note=caption(m.description);mount(this,toggle,"client.toggle."+m.name);mount(this,note,null);mount(this,settings,"client.inspect."+m.name); 074 toggle.onChange(v->{m.enabled=toggle.selected();refresh();});settings.onClick(v->selectModule(m.name));} 075 @Override protected void layoutChildren(){place(toggle,12,10,w-24,30);place(note,12,47,w-24,20);place(settings,w-74,71,62,24);} 076 } 077}