diff options
| author | Fuwn <[email protected]> | 2026-02-12 22:33:32 -0800 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2026-02-12 22:33:32 -0800 |
| commit | c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9 (patch) | |
| tree | df9f48bf128a6c0186a8e91857d6ff30fe0e9f18 /NET/worlds/scape/Sharer.java | |
| download | worldsplayer-c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9.tar.xz worldsplayer-c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9.zip | |
Initial commit
Diffstat (limited to 'NET/worlds/scape/Sharer.java')
| -rw-r--r-- | NET/worlds/scape/Sharer.java | 590 |
1 files changed, 590 insertions, 0 deletions
diff --git a/NET/worlds/scape/Sharer.java b/NET/worlds/scape/Sharer.java new file mode 100644 index 0000000..aaa03eb --- /dev/null +++ b/NET/worlds/scape/Sharer.java @@ -0,0 +1,590 @@ +package NET.worlds.scape; + +import NET.worlds.console.Console; +import NET.worlds.console.Main; +import NET.worlds.console.MainCallback; +import NET.worlds.core.Std; +import NET.worlds.network.InfiniteWaitException; +import NET.worlds.network.ObjID; +import NET.worlds.network.PacketTooLargeException; +import NET.worlds.network.PropertyList; +import NET.worlds.network.PropertySetCmd; +import NET.worlds.network.WorldServer; +import NET.worlds.network.net2Property; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.text.MessageFormat; +import java.util.Enumeration; +import java.util.Vector; + +public class Sharer extends SuperRoot implements MainCallback { + private Vector<Attribute> attributes; + private ByteArrayOutputStream bs = new ByteArrayOutputStream(); + private boolean shared = false; + public static final int FIRST_TIME = 0; + public static final int STATIC = 2; + public static final int FORWARDED_STATIC = 3; + public static final int DYNAMIC = 4; + public static final int FORWARDED_DYNAMIC = 5; + public static final int FORWARDED = 1; + private boolean createdFromNet; + Vector<Attribute> noteQ; + Vector<Attribute> prepQ; + Vector<Attribute> sendQ; + private DynamicForwardAttribute dfa; + int lastSendTime; + private static Object classCookie = new Object(); + private Vector<Object> restoredAttributes = null; + + public Sharer() { + this.attributes = new Vector<Attribute>(256); + this.attributes.setSize(256); + } + + public boolean isShared() { + return this.shared; + } + + private int getMaybeDefaultMode() { + return ((WObject)this.getOwner()).getSharerMode(); + } + + public int getMode() { + int mode = this.getMaybeDefaultMode(); + if (mode == 0) { + this.setMode(mode); + } + + return mode; + } + + public void setMode(int mode) { + WObject w = (WObject)this.getOwner(); + if (w instanceof Room) { + mode = 2; + } else if (this.createdFromNet) { + mode = 4; + } else if (mode == 2 || mode == 4) { + mode = 0; + } + + if (mode == 0) { + mode = 3; + } + + int oldMode = this.getMaybeDefaultMode(); + if (oldMode != mode) { + this.unshare(); + w.setSharerMode(mode); + } + + this.share(); + } + + public void createDynamicForwardedFromNet(DynamicForwardAttribute dfa) { + assert !((WObject)this.getOwner()).isActive(); + + this.dfa = dfa; + ((WObject)this.getOwner()).setSharerMode(5); + } + + public void createDynamicFromNet() { + assert !((WObject)this.getOwner()).isActive() || this.createdFromNet; + + this.createdFromNet = true; + ((WObject)this.getOwner()).setSharerMode(4); + } + + public void adjustShare() { + this.share(); + } + + private void share() { + if (!this.shared) { + int mode = this.getMaybeDefaultMode(); + switch (mode) { + case 0: + this.setMode(0); + case 1: + case 2: + default: + break; + case 3: + this.flushQueue(); + Enumeration<Attribute> e = this.getAttributes(); + + while (e.hasMoreElements()) { + e.nextElement().addForwarding(); + } + break; + case 4: + assert this.createdFromNet; + break; + case 5: + if (this.dfa == null) { + this.flushQueue(); + WObject w = (WObject)this.getOwner(); + WObject terminal = w.getServed(); + if (w.getSourceURL() != null && terminal != null) { + this.dfa = new DynamicForwardAttribute(-1); + if (terminal.getSharer().addAttribute(this.dfa) == -1) { + this.dfa = null; + } else { + this.dfa.connect(w); + } + } + } + } + + this.shared = true; + } + } + + private void unshare() { + if (this.shared) { + int mode = this.getMaybeDefaultMode(); + switch (mode) { + case 2: + case 4: + default: + break; + case 3: + Enumeration<Attribute> e = this.getAttributes(); + + while (e.hasMoreElements()) { + e.nextElement().unforward(); + } + break; + case 5: + if (this.dfa != null) { + this.dfa.unconnect(); + this.dfa = null; + } + } + + this.shared = false; + } + } + + public int addAttribute(Attribute a) { + this.setMode(this.getMaybeDefaultMode()); + a._attrID = this.getFreeAttrIDFor(a, a._attrID); + if (a._attrID == -1) { + return a._attrID; + } else { + try { + this.add(a); + } catch (ClassCastException var3) { + Console.println(Console.message("Cant-attach") + var3); + a._attrID = -1; + return a._attrID; + } + + this.attributes.setElementAt(a, a._attrID); + if (this.getMaybeDefaultMode() == 3) { + a.addForwarding(); + } + + return a._attrID; + } + } + + public boolean attrIDAvailable(int id) { + return this.attributes.elementAt(id) == null; + } + + private int getFreeAttrID(int id, int low, int high) { + if (id >= 20 && id <= 255 && this.attrIDAvailable(id)) { + return id; + } else { + int freeCount = this.countFree(low, high); + if (freeCount == 0) { + return -1; + } else { + int i; + label42: + while (true) { + int pos = (int)(Math.random() * freeCount); + i = low; + + while (true) { + if (this.attributes.elementAt(i) == null) { + if (--pos < 0) { + assert i <= high; + + if (i != 150 && i != 155 && i != 160) { + break label42; + } + break; + } + } + + i++; + } + } + + return i; + } + } + } + + public int getFreeAttrIDFor(Attribute a, int id) { + return a instanceof DynamicForwardAttribute ? this.getFreeAttrID(id, 210, 249) : this.getFreeAttrID(id, 100, 249); + } + + public void removeAttribute(Attribute a) { + a.detach(); + if (a.getOwner() == null) { + this.attributes.setElementAt(null, a._attrID); + } + } + + public int resetAttributeID(Attribute a, int newID) { + newID = this.getFreeAttrIDFor(a, newID); + if (newID == -1) { + return newID; + } else { + if (this.attributes.elementAt(newID) == null) { + int oldID = a._attrID; + this.attributes.setElementAt(a, newID); + this.attributes.setElementAt(null, oldID); + a._attrID = newID; + } + + return newID; + } + } + + public void moveToSlot(WObject child, int newID) { + if (child.isDynamic()) { + Sharer s = child.getSharer(); + if (s.dfa != null) { + this.resetAttributeID(s.dfa, newID); + } + } + } + + public Enumeration<Attribute> getAttributes() { + return this.getAttributesList().elements(); + } + + public Vector<Attribute> getAttributesList() { + Vector<Attribute> v = new Vector<Attribute>(this.attributes.size()); + this.fillAttributesList(v); + return v; + } + + public void fillAttributesList(Vector<Attribute> v) { + int end = this.attributes.size(); + + for (int i = 0; i < end; i++) { + Attribute a = this.attributes.elementAt(i); + if (a != null) { + v.addElement(a); + } + } + } + + public Attribute getAttribute(int id) { + try { + return this.attributes.elementAt(id); + } catch (ArrayIndexOutOfBoundsException var3) { + return null; + } + } + + public boolean isEmpty() { + return this.countFree(0, 255) == 256; + } + + public int countFree(int low, int high) { + int count = 0; + + for (int i = low; i <= high; i++) { + if (this.attributes.elementAt(i) == null) { + count++; + } + } + + return count; + } + + @Override + public void getChildren(DeepEnumeration d) { + d.addChildVectorWithNulls(this.attributes); + } + + public void noteChange(Attribute a, boolean sendTriggers) { + assert Main.isMainThread(); + + if (this.prepQ == null) { + this.noteQ = new Vector<Attribute>(); + this.prepQ = new Vector<Attribute>(); + this.sendQ = new Vector<Attribute>(); + } + + if (sendTriggers && !this.noteQ.contains(a)) { + if (this.noteQ.isEmpty() && this.prepQ.isEmpty() && this.sendQ.isEmpty()) { + Main.register(this); + } + + this.noteQ.addElement(a); + } + + Attribute fa; + if (this.getMode() == 3 && (fa = a.getForwardAttribute()) != null) { + fa.noteChange(); + } else if (this.dfa != null) { + this.dfa.noteChange(); + } else if (!this.prepQ.contains(a)) { + if (this.noteQ.isEmpty() && this.prepQ.isEmpty() && this.sendQ.isEmpty()) { + Main.register(this); + } + + this.prepQ.addElement(a); + } + } + + private void prepQueue() { + if (!this.noteQ.isEmpty()) { + int end = this.noteQ.size(); + + for (int i = 0; i < end; i++) { + Attribute a = this.noteQ.elementAt(i); + ValueEvent e = new ValueEvent(Std.getFastTime(), this.getOwner(), (WObject)this.getOwner(), a); + a.trigger(e); + } + + this.noteQ.removeAllElements(); + } + + int end = this.prepQ.size(); + + for (int i = 0; i < end; i++) { + Attribute a = this.prepQ.elementAt(i); + this.bs.reset(); + + try { + a.generateNetData(new DataOutputStream(this.bs)); + } catch (IOException var5) { + System.err.println(var5); + throw new Error("Fatal in generateNetData"); + } + + a._outgoing = this.bs.toByteArray(); + if (Std.byteArraysEqual(a._outgoing, a._serverData)) { + a._outgoing = null; + } else if (!this.sendQ.contains(a)) { + this.sendQ.addElement(a); + } + } + + this.prepQ.removeAllElements(); + } + + @Override + public void mainCallback() { + if (this.noteQ.isEmpty() && this.prepQ.isEmpty() && this.sendQ.isEmpty()) { + Main.unregister(this); + } else { + int frameTime = Std.getFastTime(); + if (frameTime > this.lastSendTime + 250) { + this.sendQueue(); + Main.unregister(this); + this.lastSendTime = frameTime; + } + } + } + + private void flushQueue() { + if (this.prepQ != null) { + this.prepQueue(); + if (!this.sendQ.isEmpty()) { + int i = this.sendQ.size(); + + while (--i >= 0) { + Attribute a = this.sendQ.elementAt(i); + a._waitingForFeedback = false; + a._serverData = null; + a._outgoing = null; + } + + this.sendQ.removeAllElements(); + } + } + } + + private void sendQueue() { + this.prepQueue(); + WorldServer rs = ((WObject)this.getOwner()).getServer(); + if (rs != null) { + int end = this.sendQ.size(); + + for (int i = 0; i < end; i++) { + Attribute a = this.sendQ.elementAt(i); + if (a._outgoing != null) { + this.share(rs, a); + a._serverData = a._outgoing; + a._outgoing = null; + a._waitingForFeedback = true; + } + } + } + + this.sendQ.removeAllElements(); + } + + private void share(WorldServer ws, Attribute a) { + SuperRoot w = this.getOwner(); + ObjID objID = null; + if (w instanceof Room) { + Pilot pilot = Pilot.getActive(); + if (pilot != null && pilot.getLastServedRoom() != w) { + objID = new ObjID(((Room)w).getNetworkRoom().getLongID()); + } else { + objID = new ObjID(253); + } + } else if (w instanceof Pilot) { + objID = new ObjID(1); + } else { + objID = new ObjID(w.getName()); + } + + try { + PropertyList propList = new PropertyList(); + propList.addProperty(new net2Property(a._attrID, a.getFlags(), a.getAccessFlags(), a._outgoing)); + ws.sendNetworkMsg(new PropertySetCmd(objID, propList)); + } catch (InfiniteWaitException var6) { + Console.println(Console.message("Net-shutdown") + var6.toString()); + } catch (PacketTooLargeException var7) { + assert false; + } + } + + public void setFromNetData(int attrID, byte[] data) { + if (this.prepQ != null) { + this.prepQueue(); + } + + Attribute a = this.getAttribute(attrID); + if (a == null) { + if ((this.getMode() & 1) != 0) { + Object[] arguments = new Object[]{new String("" + attrID), new String(this.getOwner().getName())}; + Console.println(MessageFormat.format(Console.message("Unknown-attr"), arguments)); + return; + } + + a = new DynamicForwardAttribute(attrID); + this.addAttribute(a); + } + + this.setData(a, data); + if (!a.loaded) { + a.loaded = true; + if (a.callbacks != null && a.callbacks.size() > 0) { + Enumeration<LoadedAttribute> e = a.callbacks.elements(); + + while (e.hasMoreElements()) { + LoadedAttribute la = e.nextElement(); + la.loadedAttribute(a, null); + } + + a.callbacks.removeAllElements(); + } + } + } + + private void setData(Attribute a, byte[] data) { + boolean matchesLastSent = Std.byteArraysEqual(data, a._serverData); + if (a._waitingForFeedback) { + if (!matchesLastSent) { + return; + } + + a._waitingForFeedback = false; + if (data.length != 0 || a._outgoing != null) { + return; + } + } else if (matchesLastSent) { + return; + } + + a._serverData = data; + if (Std.byteArraysEqual(data, a._outgoing)) { + a._outgoing = null; + } else if (a._outgoing == null) { + try { + a.setFromNetData(new DataInputStream(new ByteArrayInputStream(data)), data.length); + } catch (IOException var5) { + var5.printStackTrace(); + Console.println(Console.message("Unrec-format") + a.getName()); + } + + ValueEvent e = new ValueEvent(Std.getFastTime(), this, (WObject)this.getOwner(), a); + a.trigger(e); + } + } + + @Override + public Object properties(int index, int offset, int mode, Object value) throws NoSuchPropertyException { + throw new NoSuchPropertyException(); + } + + @Override + public void saveState(Saver s) throws IOException { + s.saveVersion(2, classCookie); + super.saveState(s); + s.saveVector(this.getAttributesList()); + } + + @Override + public void restoreState(Restorer r) throws IOException, TooNewException { + switch (r.restoreVersion(classCookie)) { + case 0: + this.setName(r.restoreString()); + int nSharedAtts = r.restoreInt(); + this.restoredAttributes = new Vector<Object>(nSharedAtts); + + for (int i = 0; i < nSharedAtts; i++) { + this.restoredAttributes.addElement(r.restoreString()); + } + break; + case 1: + this.setName(r.restoreString()); + this.restoredAttributes = r.restoreVector(); + break; + case 2: + super.restoreState(r); + this.restoredAttributes = r.restoreVector(); + break; + default: + throw new TooNewException(); + } + } + + public void ownerPostRestore() { + int desiredMode = this.getMaybeDefaultMode(); + ((WObject)this.getOwner()).setSharerMode(0); + this.setMode(desiredMode); + Enumeration<Object> e = this.restoredAttributes.elements(); + + while (e.hasMoreElements()) { + Attribute a = (Attribute)e.nextElement(); + this.addAttribute(a); + } + + this.restoredAttributes = null; + } + + public void releaseAuxilaryData() { + for (int i = 0; i < 256; i++) { + Attribute a = this.attributes.elementAt(i); + if (a != null) { + a.releaseAuxilaryData(); + } + } + } +} |