File Details
DeltaSync-v2.0.0
- R
- Apr 20, 2026
- 39.27 KB
- 11
- 12.0.1+10
- Classic + 4
File Name
DeltaSync-DeltaSync-v2.0.0.zip
Supported Versions
- 12.0.1
- 12.0.0
- 11.2.7
- 5.5.3
- 5.5.2
- 4.4.2
- 3.80.0
- 3.4.5
- 2.5.5
- 1.15.8
- 1.15.7
DeltaSync Changelog
[v2.0.0] (2026-04-20) - DeltaSync-1.0 mod 7 Parity with TOGProfessionMaster
New Features
DeltaSync-1.0bumped toMINOR = 7, pulling the merged TOGPM (mod 2) / PersonalShopper (mod 6) superset into the standalone repo — The two forks that had been living in consumer addons at the sameDeltaSync-1.0MAJOR are now consolidated here. Every embedder whose private copy is at mod 2, mod 6, or mod 7 will now be overridden by this packaged version (LibStub picks the highest MINOR, so both forks and future embedders converge on the CurseForge-released lib). Location:DeltaSync.lua:8.NormalizeSenderpublic method — Newlib:NormalizeSender(name)canonicalizes AceComm's inconsistent sender strings (bare"Name"on same-realm vs"Name-Realm"on cross-realm). EveryOnComm_*handler now routes thesenderarg through it before comparison or dispatch, so self-ignore and peer lookups work identically regardless of realm topology. Location:DeltaSync.lua:800.onOfferReceived(sender, data)callback onInitializeconfig — New raw-OFFER inspection hook for consumers that want to observe hash-list-broadcasts without hooking into the full P2P session state machine. Fires before the P2PSession collect window processes the offer. Location:DeltaSync.lua:418.snifferFramefallback for non-AceComm receive paths — When a consumer has a comm prefix configured withdistribution = "CHANNEL"(raw public chat channel), AceComm's:RegisterCommdoesn't fire. DeltaSync now creates a dedicatedCHAT_MSG_ADDONevent frame that dispatches to the normalOnComm_*handlers, keeping CHANNEL-distributed messages on the same receive path as GUILD/WHISPER. Location:DeltaSync.lua:570.DebugStatusslash-style command — Newlib:DebugStatus()prints a diagnostic block: namespace, MINOR, player name, registered prefixes, and AceComm wiring state. Useful when an embedder's sends are silently dropping and you need to confirm which piece of the config is missing. Location:DeltaSync.lua:1412.- Debug category/tag toggle API — New
IsCategoryEnabled/SetCategoryEnabled/IsTagEnabled/SetTagEnabledplusGetDebugFrame/CreateDebugTab/RemoveDebugTab/BufferDebugMessage/RedrawDebugMessages. Gives host addons a structured way to surface DeltaSync's debug output in their own UI (the TOGPM debug tab consumes these). Location:DeltaSync.lua:1471-1658. GetPrefixInfo/IsPrefixAvailable/GetPeerStates/GetCommStatsintrospection API — Read-only accessors for the current prefix allocation, peer sync state table, and per-channel send/receive counts. Intended for debug panels and telemetry. Location:DeltaSync.lua:1760-1800.GetProtocolVersionreturns the wire-format revision — Returns the MINOR value, for embedders that want to guard calls behind a minimum version. Location:DeltaSync.lua:1406.
Breaking Changes
aceAddonis now a requiredInitialize()config key — Mod 7 no longer embedsAceComm-3.0intolib; instead it callsself.aceAddon:SendCommMessage(...)on the host addon's own AceAddon instance. An embedder'sInitialize({...})call that omitsaceAddonwill register receive handlers (via the new CHAT_MSG_ADDON sniffer fallback) but silently fail to send, putting them in a half-broken state. Migration: addaceAddon = self(or whatever holds yourAceAddon:NewAddon(...)handle) to the config table passed toInitialize. Location:DeltaSync.lua:451,DeltaSync.lua:753.AceSerializerno longer embedded intolib—lib:Serialize(...)andlib:Deserialize(...)methods thatAceSerializer:Embed(lib)would have added are gone. The library now callsLibStub("AceSerializer-3.0"):Serialize(...)at use-time (cached in a file-local upvalue) so it stays decoupled from Ace's MINOR upgrades and doesn't duplicate methods the host addon already has. Migration: consumers that calledlib:Serializemust switch toLibStub("AceSerializer-3.0"):Serializeon their own handle. Location:DeltaSync.lua:19-25.AceCommQueue-1.0throttling responsibility moved to host addon — Because mod 7 routes sends throughself.aceAddon:SendCommMessage, the wrap target for CRC-protection queuing is the host addon, not the library. Embedders mustLibStub("AceCommQueue-1.0"):Embed(theirAceAddon)themselves immediately afterNewAddon(...), or they'll see chunk-interleaving CRC corruption under sync load.## Dependencies: AceCommQueue-1.0remains inDeltaSync.tocso load order is still enforced. Migration: one-line:Embedcall in the consumer. Location: host-addon responsibility; documented inCLAUDE.md.- Wire format is unchanged but receive paths now normalize senders —
OnComm_*handlers route thesenderargument throughNormalizeSenderbefore comparison/dispatch. Messages from older-mod embedders still decode via the legacy AceSerializer-only fallback inDeserializeWithChecksum, so no user-visible wire break. Mentioned here because "same wire format, different handler behavior" is the kind of thing that bites during migration debugging. GuildCacheextracted into its own LibStub libraryGuildCache-1.0— Previously, roster-cache methods (NormalizeName,GetNormalizedPlayer,IsPlayerOnline,IsInGuild,GetOnlineGuildMembers) hung off theDeltaSync-1.0lib handle andguildRosterwas atlib.guildRoster. These have moved to a new LibStub library with MAJORGuildCache-1.0, embedded atLibs/GuildCache-1.0/GuildCache-1.0.lua. Consumers that calledDeltaSync:NormalizeName(x)(etc.) must now callLibStub("GuildCache-1.0"):NormalizeName(x), or grab the handle once:local GC = LibStub("GuildCache-1.0"); GC:NormalizeName(x). Motivation: GuildCache is independently useful (other addons can embed it without pulling the full sync stack) and follows the same "embedded initially → external dependency later" path DeltaSync itself is on. Same pattern TOGPM uses forLibGuildRoster-1.0. Inside DeltaSync, all consumers now route through a file-local upvalue with soft-dep presence checks, so embedders that drop GuildCache get graceful degradation (inline realm derivation, no whisper online-guard, accept-allisValidPeerdefault).
Improvements
- Cross-realm
NormalizeNamecorrectness — Previous implementation's regex"^(.-)%-(.+)$"matched greedy across every hyphen in the string, which broke for realm names containing hyphens (rare but possible). Replaced withtrimmed:match("%-[^%-]+$")— only appends the local realm for bare same-server names, and leaves any existing-Realmsuffix untouched so cross-realm peers are stored per-realm correctly. Includes an explicit doc note about AceComm's inconsistent sender-realm-suffix behavior. Location:GuildCache.lua:37-61. ComputeDelta/ApplyDeltaconvenience wrappers retained — Despite the substantial DeltaSync.lua rewrite, the wrapper methods that delegate toDeltaOperations.luaremain at the same call sites so consumer code built against v1.0.0 does not need to change delta-ops call sites. Location:DeltaSync.lua:1739-1748.DeltaOperations.luaandP2PSession.luaunchanged — Both files are byte-identical to the current TOGPM copy; no merge work required. All delta/hash/P2P session machinery works exactly as in v1.0.0.
[v1.0.0] (2026-04-03) - P2P Session Hardening, CRC Integrity & GuildCache Guard
New Features
DELIVERY_TIMEOUTfor in-flight data streams — After a peer repliessync-accept, the requester now arms aDELIVERY_TIMEOUTtimer (default 180s) so a provider that accepts and then goes silent can no longer pin an inbound session slot forever. On timeout the session transitions toFAILED, the slot frees, and catch-up logic retries another peer. Location:P2PSession.lua.TryAcquireSendSlot/ReleaseSendSlotoutbound accounting — Outbound sends now use explicit slot acquisition symmetric with the inboundmaxActiveSessionsmodel. A safety timer (SEND_TIMEOUT, default 90s) auto-releases slots the host forgets to release, so a crash in the host's send path can't deadlock the sender. Public API: host callslib.p2p:ReleaseSendSlot(requester)after the wire send returns. Location:P2PSession.lua.SerializeWithChecksum/DeserializeWithChecksumwrapped around all 7 channels — Every comm path (VERSION, DATA, QUERY, RESPONSE, DELTA, OFFER, HANDSHAKE) now goes through the checksum envelope (<AceSer payload>\030<checksum>\031END). Corrupt or truncated messages are detected at the edge and dropped with an INTEGRITY-MISMATCH log line instead of feeding garbage into delta apply. Graceful legacy-format fallback keeps compatibility with addons still on the older AceSerializer-only wire. Location:DeltaSync.lua.
Bug Fixes
- OFFER/HANDSHAKE session state machine gaps — Several sequences where a peer's
hash-offerarrived after the collect window closed, or async-acceptarrived for an item the dispatch loop had already given to another peer, left orphan session state. State transitions now validate against the current session table so late messages are ignored rather than mutating unrelated sessions. Location:P2PSession.lua. - Whispering offline guild members —
lib:SendMessage()with a WHISPER distribution would happily queue messages to members who had logged out, wasting the AceComm slot and causing spurious "no such player" errors in chat. Added a guard viaGuildCache:IsPlayerOnline(target)that drops the send with a debug log when the target isn't online. Location:DeltaSync.lua.
Improvements
docs/COMMUNICATION.mdbrought in line with the 7-channel reality — Documentation still described the original 5-channel VERSION/DATA/QUERY/RESPONSE/DELTA layout. Rewrote the channel table to include OFFER and HANDSHAKE, documented the hash-list-broadcast wire format and the sync-request/sync-accept/sync-busy handshake payloads, and fixed every markdownlint warning in the file. Location:docs/COMMUNICATION.md.docs/DESIGN.mdupdated for Phase 2 completion — Marked Phase 2 (P2P session layer) as complete, rewrote the architecture diagrams to show OFFER/HANDSHAKE as separate channels from DELTA, and added the "embedded vs global shared addon" section explaining the 16-prefix budget trade-off. All markdownlint errors fixed. Location:docs/DESIGN.md.- CurseForge description refreshed — Added the v0.0.3-alpha entry to the external changelog block consumed by CurseForge's project page. Location:
docs/Curseforge_Description.html.
[v0.0.3-alpha] (2026-04-02) - Standalone GuildCache Module
New Features
GuildCache.lua— generic guild presence cache — New file providingNormalizeName,GetNormalizedPlayer,IsPlayerOnline,IsInGuild, andGetOnlineGuildMembersoff thelibhandle. Maintainslib.guildRoster(normalizedName → {isOnline, class, level, rank}) viaGUILD_ROSTER_UPDATE. Extracted so consuming addons don't each have to reinvent name normalization and roster tracking, and so the library itself can gate whispers on online state. Location:GuildCache.lua.isValidPeercallback onInitP2P— Host addons can now filter which guildmates are eligible P2P peers (e.g. rank, role, "only trust officers"). Called during offer collection and dispatch; peers that fail the check are skipped. Location:P2PSession.lua.TableContains,TableCount,ValidateDeltautility methods onlib— Small helpers previously duplicated across consumers, now exposed centrally.ValidateDeltadoes version/timestamp/hash structural checks beforeApplyStructuredDeltaruns. Location:DeltaSync.lua,DeltaOperations.lua.
Bug Fixes
- QUERY channel was still using bare AceSerializer format — Every other channel had migrated to the checksum-wrapped format, but QUERY was missed, so queries crossing the wire were not integrity-checked. Migrated to
SerializeWithChecksum/DeserializeWithChecksumfor consistency and to catch the same class of truncation bugs. Location:DeltaSync.lua. - Extra
endsyntax error inDeltaSync.lua— A strayendkept the file from loading cleanly on fresh embed. Removed. Location:DeltaSync.lua. - Duplicated utility block in
DeltaSync.lua— A block of helper functions was copy-pasted during the earlier P2P merge; the duplicate shadowed the authoritative copy. Removed. Location:DeltaSync.lua. Initialize()doc comment referenced removed parameters — Cleaned up the header block so it matches the currentconfigschema. Location:DeltaSync.lua.
Improvements
Initialize()now derives local player identity via GuildCache — Instead of each host addon passingplayerName/playerFullNamethrough config,Initialize()callsGuildCache:GetNormalizedPlayer()on first use. Hosts that still pass these values override the derived ones. Location:DeltaSync.lua.P2PSessionnormalizes senders throughNorm()/Me()helpers —OnHashListReceivedandOnOfferused to compare sender strings directly, which broke when AceComm delivered bare names vs. fully-qualified names on the same payload. All sender comparisons now go through normalization. Location:P2PSession.lua..luarc.json— WoW API globals added — Several API functions (C_Timer,GetRealmName, etc.) were missing from the LSP globals list, causing noise in the problems panel. Added them. Location:.luarc.json.- Single-consumer constraint documented — Added a header block to
P2PSession.luaclarifying that one LibStub instance serves one embedding addon (the 7-prefix budget is per-addon, not per-library). Location:P2PSession.lua. - CurseForge description — multi-consumer claim corrected — Earlier marketing text implied two addons on the same client could share one DeltaSync instance. They can't (each gets its own LibStub copy with its own prefixes); wording updated. Location:
docs/Curseforge_Description.html.
[v0.0.2-alpha] (2026-04-01) - P2P Session Protocol & Ace3 Integration
New Features
P2PSession.lua— generalized port of TOGBankClassic's P2P protocol — New file implementing the broadcast / collect / dispatch / handshake loop:lib:BroadcastItemHasheskicks off a GUILD hash-list, peers reply withhash-offerwhispers during the collect window, dispatch picks the newest peer per stale item and sends async-request, and the peer repliessync-accept(initiates data exchange) orsync-busy(try next peer). No single "banker" bottleneck — any peer with fresh data can serve. Host integrates via callbacks onInitP2P(config):getMyHashes,hasContent,hasMissingItems,onSyncAccepted,onDataRequest,onDataReceived. Location:P2PSession.lua.- OFFER and HANDSHAKE channel types — Two new addon-message prefixes (
-oand-h) take the library from 5 channels to 7 out of the 16-prefix-per-addon WoW budget. OFFER carries hash-list-broadcasts (GUILD) and hash-offer replies (WHISPER); HANDSHAKE carries the three sync-request/accept/busy messages. Location:DeltaSync.lua. - High-level P2P API on
lib—BroadcastItemHashes(items, priority),SendHashOffer(target, items, priority),SendHandshake(target, payload, priority). These are thin wrappers overSendMessagebut document the protocol intent. Location:DeltaSync.lua. - Full CRC wire-format framework —
SerializeWithChecksum/DeserializeWithChecksumwrap every outgoing payload with an ASCII RS separator (\030), an additive checksum, and a stop marker (\031END). The deserializer does best-effort corrupt-payload decoding on INTEGRITY-MISMATCH so a debug log can still show what the peer was trying to send. Location:DeltaSync.lua.
Improvements
- Serialization switched from custom built-in to AceSerializer-3.0 — The earlier length-prefixed
SerializeData/DeserializeData(added in v0.0.1-alpha) was functional but every consuming addon already embedded AceSerializer anyway. Switched toAceSerialization-3.0via LibStub and embed it alongside AceComm/AceCommQueue inRegisterCommChannels, eliminating ~150 lines of hand-rolled serializer code. Location:DeltaSync.lua. AceCommQueue-1.0andAce3declared as hard dependencies —DeltaSync.tocnow lists them under## Dependencies, enforcing load order. Previous bundled copies underLibs/removed since AceCommQueue is shipped as a standalone addon. Location:DeltaSync.toc..pkgmetatightened for CurseForge release — Addedrequired-dependencies(initiallyace3,AceCommQueue-1.0), removed the now-unusedexternalsblock, and expanded theignorelist to catchdocs/**,*.ps1,*.bat, and the code-workspace file so they don't end up in the zip. Location:.pkgmeta.
Bug Fixes
AceCommQueue-1.0listed as a CurseForge required-dependency caused a 400/1018 upload error — CurseForge only accepts slugs for projects published on its platform; AceCommQueue is GitHub-only, so declaring it inrequired-dependencies:broke uploads. Removed from.pkgmetarequired-dependencies — load order is still enforced via## Dependencies:inDeltaSync.toc, which is all WoW actually cares about. Location:.pkgmeta.
[v0.0.1-alpha] (2026-03-17) - Initial Library Extraction from TOGBankClassic
New Features
- Library skeleton as
DeltaSync-1.0via LibStub — First pass at the standalone library, extracted and generalized from TOGBankClassic's proven delta sync system. Target: any WoW addon that needs guild-scoped P2P data sync can embed this library and get 90-99% bandwidth reduction on updates. Location:DeltaSync.lua,DeltaSync.toc. - Built-in length-prefixed serializer —
SerializeData/DeserializeDatareplace the earliertostring()placeholder with a real type-tagged format supporting tables, strings, numbers, booleans, nil, and circular-reference protection. (Superseded in v0.0.2-alpha by AceSerializer, but the API surface remains so host addons don't have to change call sites.) Location:DeltaSync.lua. ComputeDelta()/ApplyDelta()convenience wrappers onlib— Shorthand that delegates toComputeStructuredDelta/ApplyStructuredDeltainDeltaOperations.luaso hosts don't have to know the module split. Location:DeltaSync.lua.- Self-ignore on all 5 message handlers — VERSION, QUERY, RESPONSE, DATA, and DELTA now drop messages whose sender matches the local player. Handled for both bare
UnitNameand fully-qualifiedName-Realmformats because AceComm delivers either depending on realm context. Without this, every broadcast you sent came back and triggered your own handlers. Location:DeltaSync.lua.
Bug Fixes
- Duplicate
ValidateDelta()inDeltaSync.lua— A stub version shadowed the complete implementation inDeltaOperations.lua(which does full version/timestamp/hash validation). Removed the stub so the authoritative one is always used. Location:DeltaSync.lua.
Improvements
playerNameandplayerFullNamestored duringInitialize()— Cached onlibat init time so handlers don't re-query the WoW API on every incoming message. Location:DeltaSync.lua.