screeps-client 0.12.0 → 0.12.1
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.
- package/README.md +70 -0
- package/dist/embedded/_client/{CodePanel-D5ETgtFO.js → CodePanel-DqEroeo0.js} +1 -1
- package/dist/{standalone/_client/MapViewer-yzB_3QH9.js → embedded/_client/MapViewer-CtTLbar9.js} +1 -1
- package/dist/embedded/_client/{index-EZziD5mv.js → index-DexRZi-6.js} +3 -3
- package/dist/embedded/index.html +1 -1
- package/dist/{xxscreeps-mod/_client/CodePanel-CcplJf29.js → standalone/_client/CodePanel-CUV7Ll5N.js} +1 -1
- package/dist/{embedded/_client/MapViewer-DFQ7jJZw.js → standalone/_client/MapViewer-CWn3zHVX.js} +1 -1
- package/dist/standalone/_client/{index-D88gazCV.js → index-DN_TgibB.js} +3 -3
- package/dist/standalone/index.html +1 -1
- package/dist/{standalone/_client/CodePanel-DzUWmwLB.js → xxscreeps-mod/_client/CodePanel-DBXMb7Nm.js} +1 -1
- package/dist/xxscreeps-mod/_client/{MapViewer-PPsdyxO4.js → MapViewer-D_JcCkwf.js} +1 -1
- package/dist/xxscreeps-mod/_client/{index-CPAabLyi.js → index-DnhFrpHG.js} +3 -3
- package/dist/xxscreeps-mod/index.html +1 -1
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# screeps-client
|
|
2
|
+
|
|
3
|
+
Browser client for [Screeps](https://screeps.com) private servers. Built with [SolidJS](https://solidjs.com) and [PixiJS](https://pixijs.com).
|
|
4
|
+
|
|
5
|
+
This package contains the compiled client bundle. To serve it on your server, install one of the mod packages instead of using this package directly:
|
|
6
|
+
|
|
7
|
+
| Server | Mod package |
|
|
8
|
+
|---|---|
|
|
9
|
+
| [screeps/private-server](https://github.com/screeps/screeps) | [`screepsmod-client-new`](https://www.npmjs.com/package/screepsmod-client-new) |
|
|
10
|
+
| [xxscreeps](https://github.com/laverdet/xxscreeps) | [`xxscreeps-mod-client`](https://www.npmjs.com/package/xxscreeps-mod-client) |
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Features
|
|
15
|
+
|
|
16
|
+
- **Room view** — terrain, structures, creeps with smooth movement, Screeps visuals, attack/heal animations
|
|
17
|
+
- **World map** — minimap tiles, owner badges, minerals, reservation/RCL overlay, room tooltip
|
|
18
|
+
- **Console** — live output with input, log filtering, auto-scroll
|
|
19
|
+
- **Code editor** — CodeMirror-based branch editor
|
|
20
|
+
- **Account** — overview page (GCL/GPL rings, stats), per-room minimap previews, power creeps
|
|
21
|
+
- **Market** — all orders, my orders, and transaction history
|
|
22
|
+
- Supports `screepsmod-auth` (password, Steam, GitHub, GitLab) and guest/read-only access (xxscreeps)
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Development
|
|
27
|
+
|
|
28
|
+
```sh
|
|
29
|
+
# from repo root
|
|
30
|
+
pnpm install
|
|
31
|
+
pnpm dev # starts the Vite dev server for screeps-client
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
The dev server proxies API requests to a real Screeps server — configure the target in `screeps-client/vite.config.ts`.
|
|
35
|
+
|
|
36
|
+
`screeps-connectivity` is a workspace dependency with a `"development"` export condition pointing at its TypeScript source, so you **don't** need to build it before running `pnpm dev`.
|
|
37
|
+
|
|
38
|
+
### Build
|
|
39
|
+
|
|
40
|
+
```sh
|
|
41
|
+
pnpm build # build connectivity, then the client
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Individual build targets inside `screeps-client/`:
|
|
45
|
+
|
|
46
|
+
```sh
|
|
47
|
+
pnpm build # standard browser bundle
|
|
48
|
+
pnpm build:embedded # embedded bundle at /client/ (for screepsmod-client-new)
|
|
49
|
+
pnpm build:embedded:xxscreeps # embedded bundle for xxscreeps-mod-client
|
|
50
|
+
pnpm build:all # all three
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Lint / test
|
|
54
|
+
|
|
55
|
+
```sh
|
|
56
|
+
pnpm lint
|
|
57
|
+
pnpm test
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Repository
|
|
63
|
+
|
|
64
|
+
This package is part of the [`screeps-client`](https://github.com/bastianh/screeps-client) monorepo.
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## License
|
|
69
|
+
|
|
70
|
+
ISC
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{S as e,_ as t,a as n,d as r,g as i,i as a,n as o,o as s,p as c,r as l,t as u,y as d}from"./vendor-codemirror-B6f_i0wP.js";import{S as f,_ as p,b as m,f as h,g,v as _,x as v,y}from"./index-
|
|
1
|
+
import{S as e,_ as t,a as n,d as r,g as i,i as a,n as o,o as s,p as c,r as l,t as u,y as d}from"./vendor-codemirror-B6f_i0wP.js";import{S as f,_ as p,b as m,f as h,g,v as _,x as v,y}from"./index-DexRZi-6.js";var b=v(`<span style=font-size:11px;color:#e3b341>Unsaved changes`),x=v(`<div style="padding:12px 10px;font-size:12px;color:#484f58;font-style:italic">Loading…`),S=v(`<div style=flex:1;display:flex;align-items:center;justify-content:center;color:#484f58;font-size:13px;font-style:italic>`),C=v(`<div style=position:absolute;inset:0px;background:#0d1117;z-index:100;display:flex;flex-direction:column;overflow:hidden><div style="display:flex;align-items:center;gap:12px;padding:10px 16px;border-bottom:1px solid #30363d;flex-shrink:0"><span style=font-size:15px;font-weight:600;color:#c9d1d9>Code</span><select style="background:#010409;color:#c9d1d9;border:1px solid #30363d;border-radius:4px;padding:4px 8px;font-size:12px;cursor:pointer"></select><div style=flex:1></div><button style="padding:5px 14px;border-radius:4px;border:1px solid #238636;font-size:12px;font-weight:600"></button><button style="background:transparent;border:none;color:#8b949e;font-size:18px;cursor:pointer;line-height:1;padding:2px 6px">✕</button></div><div style=flex:1;display:flex;overflow:hidden><div style="width:180px;flex-shrink:0;border-right:1px solid #21262d;display:flex;flex-direction:column;overflow:hidden"><div style="padding:6px 10px;font-size:10px;font-weight:700;color:#8b949e;text-transform:uppercase;letter-spacing:0.06em;border-bottom:1px solid #21262d;flex-shrink:0">Modules</div><div style=flex:1;overflow:auto></div></div><div style=flex:1;display:flex;flex-direction:column;overflow:hidden><div style="padding:5px 14px;font-size:12px;color:#8b949e;border-bottom:1px solid #21262d;flex-shrink:0;font-family:monospace;background:#0d1117">.js</div><div style=flex:1;overflow:hidden;flex-direction:column>`),w=v(`<option>`),T=v(`<div style="padding:7px 12px;font-size:12px;cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis">`),{error:E}=g(`code`),D=s.theme({"&":{height:`100%`},".cm-scroller":{"font-family":`'JetBrains Mono', 'Fira Code', 'Cascadia Code', monospace`,"font-size":`13px`,"line-height":`1.6`,overflow:`auto`},".cm-gutters":{background:`#0d1117`,"border-right":`1px solid #21262d`},".cm-lineNumbers .cm-gutterElement":{color:`#484f58`,"min-width":`3em`},".cm-activeLineGutter":{background:`#161b22`},".cm-activeLine":{background:`#161b22`}}),O=[l,o(),u,D];function k(o){let[s,l]=e([]),[u,g]=e(``),[_,v]=e({}),[D,k]=e(``),[A,j]=e(!1),[M,N]=e(!1),[P,F]=e(!1),I=()=>Object.keys(_()),{editorView:L,ref:R,createExtension:z}=n({onValueChange:e=>{let t=D();!t||_()[t]===e||(v(n=>({...n,[t]:e})),F(!0))}});a(L,()=>_()[D()]??``),z(O),t(()=>{let e=h();e&&e.http.user.branches().then(e=>{l(e.list);let t=e.list.find(e=>e.activeWorld)??e.list[0];t&&g(t.branch)}).catch(e=>{E(`branches failed:`,e),p(`Failed to load branches`,`error`)})}),t(()=>{let e=u(),t=h();!e||!t||(j(!0),v({}),k(``),F(!1),t.http.user.code.get(e).then(e=>{let t=e.modules??{};v(t),k(Object.keys(t)[0]??``)}).catch(e=>{E(`get failed:`,e),p(`Failed to load code`,`error`)}).finally(()=>j(!1)))});let B=()=>{let e=h(),t=u();!e||!t||(N(!0),e.http.user.code.set(t,_()).then(()=>{p(`Code saved`,`success`),F(!1)}).catch(e=>{E(`set failed:`,e),p(`Failed to save code`,`error`)}).finally(()=>N(!1)))};return(()=>{var e=C(),t=e.firstChild,n=t.firstChild.nextSibling,a=n.nextSibling.nextSibling,l=a.nextSibling,p=t.nextSibling.firstChild,h=p.firstChild.nextSibling,_=p.nextSibling,v=_.firstChild,E=v.firstChild,O=v.nextSibling;return n.addEventListener(`change`,e=>g(e.currentTarget.value)),y(n,i(r,{get each(){return s()},children:e=>(()=>{var t=w();return y(t,()=>e.branch,null),y(t,()=>e.activeWorld?` ★`:``,null),d(()=>t.value=e.branch),t})()})),y(t,i(c,{get when(){return P()},get children(){return b()}}),a),a.$$click=B,y(a,()=>M()?`Saving…`:`Save`),l.$$click=()=>o.onClose(),y(h,i(c,{get when(){return A()},get children(){return x()}}),null),y(h,i(r,{get each(){return I()},children:e=>(()=>{var t=T();return t.$$click=()=>k(e),y(t,e),d(n=>{var r=D()===e?`#1f3158`:`transparent`,i=D()===e?`#58a6ff`:`#c9d1d9`,a=`2px solid ${D()===e?`#388bfd`:`transparent`}`;return r!==n.e&&m(t,`background`,n.e=r),i!==n.t&&m(t,`color`,n.t=i),a!==n.a&&m(t,`border-left`,n.a=a),n},{e:void 0,t:void 0,a:void 0}),t})()}),null),y(v,D,E),f(R,O),y(_,i(c,{get when(){return!D()},get children(){var e=S();return y(e,()=>A()?`Loading code…`:`Select a module`),e}}),null),d(e=>{var t=M()||A()||!P(),n=M()||!P()?`#161b22`:`#1a3a2a`,r=M()||!P()?`#484f58`:`#3fb950`,i=M()||!P()?`default`:`pointer`,o=D()?`block`:`none`,s=D()?`flex`:`none`;return t!==e.e&&(a.disabled=e.e=t),n!==e.t&&m(a,`background`,e.t=n),r!==e.a&&m(a,`color`,e.a=r),i!==e.o&&m(a,`cursor`,e.o=i),o!==e.i&&m(v,`display`,e.i=o),s!==e.n&&m(O,`display`,e.n=s),e},{e:void 0,t:void 0,a:void 0,o:void 0,i:void 0,n:void 0}),d(()=>n.value=u()),e})()}_([`click`]);export{k as CodePanel};
|
package/dist/{standalone/_client/MapViewer-yzB_3QH9.js → embedded/_client/MapViewer-CtTLbar9.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{D as e,O as t,S as n,_ as r}from"./vendor-codemirror-B6f_i0wP.js";import{S as i,a,c as o,d as s,f as c,g as l,h as u,i as d,l as f,m as p,n as m,o as h,p as g,r as _,s as v,t as y,u as b,x}from"./index-
|
|
1
|
+
import{D as e,O as t,S as n,_ as r}from"./vendor-codemirror-B6f_i0wP.js";import{S as i,a,c as o,d as s,f as c,g as l,h as u,i as d,l as f,m as p,n as m,o as h,p as g,r as _,s as v,t as y,u as b,x}from"./index-DexRZi-6.js";var S=x(`<div style=width:100%;height:100%;position:relative><canvas style=display:block>`),{log:C,error:w}=l(`map`);function T(l){let x,T=null,[E,D]=n([]),[O,k]=n(1),[A,j]=n(l.originRoom??null),M=null,N=null,P=new Map,F=new Map,I=new Map,L=new Map,R=e=>{let t=u();if(!t)return!0;let n=o(e);return!!n&&v(n.x,n.y,t)},z=e=>{let t=F.get(e),n=t?.own,r=t?.username??(n?.user?`user:${n.user}`:null),i=!!n&&n.level>=1,a=!!n&&n.level===0,o=t?.sign;return{room:e,owner:i?r:null,reservation:a?r:null,level:i?n.level:null,mineral:t?.mineral??null,density:t?.density??null,badge:t?.badge??null,sign:o?{text:o.text,datetime:o.datetime,username:o.username??(o.user?`user:${o.user}`:null),badge:o.badge??null}:null}},B=[],V=null,H=new Set,U=()=>{V=null;let e=c();if(!e||!T)return;let t=new Set(E());if(B=B.filter(e=>t.has(e)&&!T.hasRoom(e)&&!H.has(e)),B.length===0)return;let n=B.splice(0,200);for(let e of n)H.add(e);e.stores.room.terrainBulk(n,l.shard).then(async e=>{let t=[];for(let[n,r]of e){let e=T?.setRoomTerrain(n,r);e&&t.push(e);let i=I.get(n);i!==void 0&&T?.setRoomOwned(n,i)}for(let t of n)e.has(t)||T?.markRoomFetched(t);await Promise.all(t)}).catch(e=>w(`terrain fetch failed:`,e)).finally(()=>{for(let e of n)H.delete(e);B.length>0&&(V=setTimeout(U,0))})};return r(()=>{c(),l.shard,F.clear(),I.clear()}),t(()=>{x&&(async()=>{if(T=new y({onRoomHover:e=>{l.onHoveredRoomChanged?.(e?z(e):null)},onRoomClick:e=>{A()===e?R(e)&&setTimeout(()=>l.onNavigateToRoom(e),0):(j(e),T?.setSelectedRoom(e),l.onSelectedRoomChanged?.(z(e)))},onVisibleRoomsChanged:e=>{let t=e.length===0;N!==t&&(N=t,C(t?`zoom out — too many rooms visible, terrain loading paused`:`zoom in — terrain loading active, ${e.length} rooms visible`)),D(e)},onZoomChanged:e=>{k(e),l.onZoomChanged?.(e)}}),await T.init(x),!T)return;l.initialZoom!==void 0&&l.initialZoom>0&&T.setZoom(l.initialZoom),l.onZoomChanged?.(T.zoom);let e=u();if(e&&T.setBounds(e.minX,e.maxX,e.minY,e.maxY),l.originRoom){let e=o(l.originRoom);e&&T.centerOn(e.x,e.y),T.setSelectedRoom(l.originRoom),l.onSelectedRoomChanged?.(z(l.originRoom))}else{let e=c();if(e)try{let t=await e.http.user.worldStartRoom(l.shard??`shard0`);if(!T)return;let n=Array.isArray(t?.room)?t.room[0]:t?.room;if(typeof n==`string`){let e=o(n);e&&T.centerOn(e.x,e.y)}}catch(e){w(`worldStartRoom failed:`,e)}}})()}),e(()=>{V!==null&&(clearTimeout(V),V=null),B=[],H.clear();for(let e of P.values())e.dispose();P.clear(),T?.destroy(),T=null}),r(()=>{_({currentRoom:A,worldBounds:u,onMove:(e,t)=>{let n=d(e,t);j(n),T?.setSelectedRoom(n),T?.centerOn(e,t,!0),l.onSelectedRoomChanged?.(z(n)),l.onHoveredRoomChanged?.(z(n))}});let t=e=>{let t=e.target?.tagName??``,n=e.target?.isContentEditable??!1;if(!(t===`INPUT`||t===`TEXTAREA`||n)&&e.key===`m`){let e=A();e&&R(e)&&l.onNavigateToRoom(e)}};window.addEventListener(`keydown`,t),e(()=>window.removeEventListener(`keydown`,t))}),r(()=>{let e=c(),t=E(),n=l.shard;if(!e||t.length===0)return;let r=new Set(t),i=t.filter(e=>!T?.hasRoom(e)&&!H.has(e));if(i.length>0){let e=t.reduce((e,t)=>e+(o(t)?.x??0),0)/t.length,n=t.reduce((e,t)=>e+(o(t)?.y??0),0)/t.length;B=i.slice().sort((t,r)=>{let i=o(t),a=o(r);return(i?Math.abs(i.x-e)+Math.abs(i.y-n):999)-(a?Math.abs(a.x-e)+Math.abs(a.y-n):999)}),V===null&&(V=setTimeout(U,0))}e.stores.mapStats.request(t,`owner0`,n??void 0);let a=O()>=.4;if(a!==M&&(M=a,l.onSubscriptionStateChanged?.(a),a||T?.clearAllMap2()),a){let r=new Set(t.map(e=>`${e}/${n}`));for(let[e,t]of P)r.has(e)||(t.dispose(),P.delete(e),T?.clearRoomMap2(e.split(`/`)[0]));for(let r of t){let t=`${r}/${n}`;P.has(t)||P.set(t,e.stores.map.subscribeMap2(r,n))}}else{for(let[,e]of P)e.dispose();P.clear()}T?.clearInvisibleRooms(r)}),r(()=>{T?.setShowRoomNames(f()),T&&(T.currentShard=l.shard??`shard0`)}),r(()=>{T?.setUnclaimableOverlayVisible(s())}),r(()=>{T?.setMapVisualVisible(b())}),r(()=>{T?.setOverlayMode(m())}),r(()=>{let e=c(),t=l.shard;e&&e.stores.server.worldInfo(t??void 0).then(e=>{C(`worldInfo(shard=${t??`none`}) — x: [${e.minX}, ${e.maxX}] y: [${e.minY}, ${e.maxY}]`),g(e)}).catch(e=>{C(`worldInfo(shard=${t??`none`}) failed:`,e)})}),r(()=>{T?.setCurrentUser(p()?._id??null)}),r(()=>{let e=u();e?(T?.setBounds(e.minX,e.maxX,e.minY,e.maxY),C(`worldBounds applied — shard: ${l.shard??`none`} x: [${e.minX}, ${e.maxX}] y: [${e.minY}, ${e.maxY}] (fetched for shard: ${e.shard??`none`})`)):(T?.clearBounds(),C(`worldBounds — none (shard: ${l.shard??`none`})`))}),r(()=>{let t=c();if(!t)return;let n=t.stores.user.subscribeMapVisual(l.shard),r=t.stores.user.on(`user:mapVisual`,({shard:e,data:t})=>{e===l.shard&&(t?T?.setMapVisual(t):T?.clearMapVisual())});e(()=>{n.dispose(),r.dispose()})}),r(()=>{let t=c();if(!t)return;let n=t.stores.map.on(`room:map2update`,({room:e,shard:t,data:n,source:r})=>{t===l.shard&&T?.setRoomMap2(e,n,r)});e(()=>n.dispose())}),r(()=>{let t=c();if(!t)return;let n=p()?._id,r=new Set(E()),i=t.stores.mapStats.on(`mapStats:room`,({room:e,stat:t})=>{F.set(e,t);let i=o(e),s=i?a(i.x,i.y)||h(i.x,i.y):!1,c=t.status===`out of borders`,u=!!(t.own&&t.own.user===n),d=!!(t.own&&t.own.user!==n),f=u?`own`:s||c||d?`other`:`none`;I.set(e,f),r.has(e)&&(T?.setRoomOwned(e,f),T?.setRoomSafeMode(e,!!t.safeMode)),T?.setRoomMineral(e,t.mineral,t.density);let p=t.badge?JSON.stringify(t.badge):``;L.get(e)!==p&&(L.set(e,p),T?.setRoomBadge(e,t.badge,t.own?.level)),A()===e&&l.onSelectedRoomChanged?.(z(e))});e(()=>i.dispose())}),(()=>{var e=S(),t=e.firstChild;return i(e=>x=e,t),e})()}export{T as MapViewer};
|