vanilla-wow-addons – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 --[[
2 The SW Sync Channel
3  
4 ]]--
5  
6 SW_SyncPassiveMode = false;
7  
8 SW_SyncMsgs = {};
9  
10 SW_S_DetailsSynced = {};
11 SW_S_HealedSynced = {};
12  
13 --1.5 added deathcounter to sync
14 SW_DCSynced = {};
15  
16 --1.5.1 added decurse count syncing
17 SW_DecurseCSynced = {};
18  
19 -- holds "lost" mana info
20 SW_ManaAfterDrop = {0,0,0};
21  
22 SW_SyncSessionID = 1;
23  
24 SW_SyncChanID = 0;
25 -- var that hold info if we are leaving the SyncChannel
26 SW_SyncLeavingChannel = false;
27  
28 -- used to see if the person is still there
29 SW_LITimerDead = 300;
30  
31 -- 1.42 added timeframe in which to accept session id updates without a RE
32 -- (joining a running channel)
33 SW_SessIDTimerThresh = 210 ; -- in this imeframe we will have at least an LI once
34 SW_SessIDTimer = time();
35  
36 -- 1.5.3 increased val buffer from 3% to 10%
37 SW_ValBuffer = 10 -- % this is used to check if somebody else needs to post info even though this was a self info (user dropped)
38 SW_DecurseBuffer = 3; --same as above but not as %
39  
40 -- time in seconds to assume the person in the channel has "up to date" info
41 -- eg he drops and reconnects checked in SW_SyncSend
42 SW_SyncKeepTime = 300;
43  
44 SW_S_LastManaSent = {0,0,0};
45  
46 -- 1.5 added, used to stop sending unneeded messages on relogging
47 SW_StartupTime = time();
48 SW_SyncIgnoreNil = 120;
49  
50 SW_Sync_MsgTrack = {};
51  
52 --[[ The sync Queue
53 So we dont have to think about timing record length etc
54 only thing to consider is that one single message may not be larger then 255 chars
55 but we use short strings here anyways
56 ]]--
57  
58  
59 SW_SyncQueue =
60 {
61 first = 1,
62 last = 0,
63 maxBlockLen = 255,
64 sep = '"',
65 sepLen = 1,
66 queue = {},
67 clearing = false,
68 itemSep = '~',
69  
70 PushSWInfo = function (self, infType, vals)
71 if self.clearing then return false; end
72 if SW_Settings["SYNCLastChan"] == nil then return; end
73 if SW_SyncChanID == 0 then return; end
74  
75 local tmpVal;
76 local outStr = infType.." ";
77 local valLen =0;
78 local ident = SW_SyncPepper[infType];
79 local sCount=0;
80 local iCount=0;
81 if vals == nil then
82 vals = { math.random(100) };
83 end
84  
85 valLen = table.getn(vals);
86 for i,v in ipairs(vals) do
87 tmpVal = tonumber(v);
88 if tmpVal == nil then
89 sCount = sCount + 1;
90  
91 else
92 iCount = iCount + 1;
93 ident = ident + tmpVal;
94  
95  
96 end
97 outStr = outStr..v;
98 if i ~= valLen then
99 outStr = outStr..self.itemSep
100 end
101 end
102  
103  
104 tmpVal = math.floor(math.sqrt(ident * string.len(SW_Settings["SYNCLastChan"]))) * 1000;
105 ident = math.floor(1000 * math.sqrt(ident * string.len(SW_Settings["SYNCLastChan"])));
106  
107 self:PushVal(SW_SyncSessionID.." "..(ident-tmpVal).." "..sCount.." "..iCount.." "..outStr);
108 --self:PushVal(SW_SyncSessionID.." "..outStr);
109 end,
110 PushVal = function (self, val)
111 if string.len(val) > self.maxBlockLen or self.clearing then return false; end
112 local last = self.last + 1;
113 self.last = last;
114 self.queue[last] = val;
115 return true;
116 end,
117 PopStack = function (self)
118 if self.clearing then return nil; end
119  
120 local last = self.last;
121 if self.first > last then return nil; end
122 local val = self.queue[last];
123 self.queue[last] = nil;
124 self.last = last - 1;
125 return val;
126 end,
127 Pop = function (self)
128 if self.clearing then return nil; end
129 local first = self.first;
130 if first > self.last then return nil; end
131 local val = self.queue[first];
132 self.queue[first] = nil;
133 self.first = first + 1;
134 return val;
135 end,
136 HasData = function (self)
137 if self.clearing then return false; end
138 return not (self.first > self.last);
139 end,
140 Clear = function (self)
141 self.clearing = true;
142 for i=self.first, self.last do
143 self.queue[i] = nil;
144 self.first = i + 1;
145 end
146 self.clearing = false;
147 end,
148 PopBlock = function (self)
149 if self.clearing then return nil; end
150 local first = self.first;
151 if first > self.last then return nil; end
152 local sepsLen = self.sepLen;
153 local pos = first;
154 local len = string.len(self.queue[first]);
155 while self.queue[pos + 1] and len + string.len(self.queue[pos + 1]) + sepsLen < self.maxBlockLen do
156 pos = pos + 1;
157 sepsLen = sepsLen + self.sepLen;
158 len = len + string.len(self.queue[pos]);
159 end
160 local val = table.concat(self.queue, self.sep, first, pos);
161 for i=first, pos do
162 self.queue[i] = nil;
163 self.first = i + 1;
164 end
165 return val;
166 end,
167 -- to lazy wouldn't work if + is a sep in the queue not using %
168 -- because this goes through chat and the profanity filter could alter the str and add a %
169 EncStr = function (self, str)
170 local sOut = string.gsub(str, "([%"..self.sep.."%"..self.itemSep.."%+%|])",
171 function(c)
172 return string.format ("+%02X", string.byte(c))
173 end);
174 return sOut;
175 end,
176 DecStr = function (self, str)
177 local sOut = string.gsub (str, "%+(%x%x)",
178 function(h)
179 return string.char(tonumber(h,16))
180 end);
181 return sOut;
182 end,
183  
184 };
185  
186 function SW_SyncSend()
187 -- this only happens when logging out and comeing back in or when leaving sync channel
188 if SW_SyncChanID ~= 0 and SW_Settings["SYNCLastAction"] ~= nil and time() - SW_Settings["SYNCLastAction"] > SW_SyncKeepTime then
189 -- are we still in this channel?
190 id, _ = GetChannelName(SW_Settings["SYNCLastChan"]);
191 if id == 0 then
192 SW_SyncChanID = 0;
193 SW_Settings["SYNCLastChan"] = nil;
194 if SW_S_DetailsSynced[SW_SELF_STRING] ~= nil then
195 SW_S_DetailsSynced[SW_SELF_STRING]["LI"] = nil;
196 end
197 return;
198 end
199 -- if we get here we are still in the channel and need a reset
200 SW_printStr("Reset in SyncSend");
201 SW_SessIDTimer = time();
202 SW_SyncReset(1);
203 return;
204 end
205 if SW_SyncChanID == 0 and SW_Settings["SYNCLastChan"] ~= nil then
206 SW_SyncChanID, _ = GetChannelName(SW_Settings["SYNCLastChan"]);
207 end
208  
209 local toSend = SW_SyncQueue:PopBlock();
210 if toSend ~= nil then
211 if SW_SyncChanID ~= 0 then
212 SendChatMessage(toSend, "CHANNEL", nil, SW_SyncChanID);
213 end
214 end
215 if SW_SyncLeavingChannel then
216 SW_SyncLeavingChannel = false;
217 SW_SyncChanID = 0;
218 LeaveChannelByName(SW_Settings["SYNCLastChan"]);
219 SW_Settings["SYNCLastChan"] = nil;
220 SW_Settings["SYNARP"] = nil;
221 SW_BarFrame1_Title_SyncIcon:Hide();
222 end
223 end
224 -- used to un/compress ints that are being sent
225 -- not sure about WOW but looking at utf im assuming we have only the lower 127 chars available for 1 byte storage
226 -- minus the lower 32 that are special chars - minus " " (space) - '"' (doublequote) which we want to use
227 -- DOH and dont use \ .. escape codes
228 -- DOH what about pipe??
229  
230 -- taking it out atm its making more problems than doing good
231 --[[
232 SW_SyncInt = {
233 digits = {},
234 rev = {},
235 base = 10;
236 Init = function(self, base)
237 --[[
238 self.base = base;
239 self.digits = {};
240 self.rev = {};
241 for i=0,9 do self.digits[i] = string.char(48+i) end
242 for i=10,71 do self.digits[i] = string.char(55+i) end -- dont add 127 (DEL)
243 for i=72,84 do self.digits[i] = string.char(119-i) end --go back in the table from before "0" and stop before '"'
244 self.digits[85] = "!";
245 for i=86,92 do self.digits[i] = string.char(150-i) end
246 --]]
247 self.base = base;
248 self.rev = {};
249 self.digits = {"1","2","3","4","5","6","7","8","9",
250 "A","B","C","D","E","F","G","H","I","J",
251 "K","L","M","N","O","P","Q","R","S","T",
252 "U","V","W","X","Y","Z","a","b","c","d",
253 "e","f","g","h","i","j","k","l","m","n",
254 "o","p","q","r","s","t","u","v","w","x",
255 "y","z","!","#","$","%","&","(",")",
256 "*","+","-",".","/",":",";","<","=",">",
257 "?","@","^","_","{","}",
258 };
259 --"y","z","!","#","$","%","&","'","(",")",
260 --"?","@","[","]","^","_","{","}","~",
261  
262 self.digits[0] = "0";
263  
264 for i,v in ipairs(self.digits) do
265 self.rev[v] = i;
266 end
267 self.rev[ self.digits[0] ] = 0;
268 end,
269  
270 Enc = function(self, number)
271 local s = "";
272 local remainder = 0;
273 repeat
274 remainder = math.mod(number,self.base);
275 s = self.digits[remainder]..s;
276 number = (number-remainder)/self.base;
277 until number==0
278 return s;
279 end,
280 Dec = function(self, number)
281 local num = 0;
282 local sLen = string.len(number);
283 for i=1,sLen do
284 num = num + (self.rev[string.sub(number,i,i)] * self.base ^ (sLen - i));
285 end
286 return num;
287 end,
288 };
289 ]]--
290  
291 -- reset
292 -- 1.4.2 changed this it will only reset yourself if your A or L
293 -- and others will check if the sender is A or L
294 -- 1.5.beta.1 added a "force self reset" for completion on a reset vote
295 function SW_SyncReset(newSessID, issuedBy, selfForce)
296  
297 if newSessID ~= nil then
298 if issuedBy ~= nil then
299 -- 1.5.3 very ralrely some events don't fire
300 -- if sombody has an A or is L might not be known so added this
301 -- drawback: somebody with A might have started RE, then had A revoked milliseconds after he sent the msg
302 -- oh hell can't catch em all
303 SW_RebuildFriendList();
304 end
305 if (issuedBy == nil and (time()-SW_SessIDTimer) < SW_SessIDTimerThresh)
306 or (issuedBy ~= nil and SW_Friends[issuedBy] ~= nil and SW_Friends[issuedBy].Rank > 0) then
307 SW_SyncQueue.clearing = true;
308 SW_ResetInfo();
309 SW_S_DetailsSynced = {};
310 SW_S_HealedSynced = {};
311 SW_DCSynced = {};
312 SW_ManaAfterDrop = {0,0,0};
313 SW_SyncSessionID = tonumber(newSessID);
314 SW_Settings["SYNCLastAction"] = time();
315 SW_SyncQueue:Clear();
316 end
317  
318 else
319 if SW_Friends[SW_SELF_STRING].Rank > 0 or selfForce then
320 SW_SyncQueue.clearing = true;
321 SW_ResetInfo();
322 SW_S_DetailsSynced = {};
323 SW_S_HealedSynced = {};
324 SW_DCSynced = {};
325 SW_ManaAfterDrop = {0,0,0};
326 SW_SyncQueue:Clear();
327 SW_SyncSessionID = SW_SyncSessionID + 1;
328 end
329 if SW_Friends[SW_SELF_STRING].Rank > 0 and (not selfForce) then
330 SW_SyncQueue:PushSWInfo("RE");
331 end
332 end
333  
334  
335 end
336  
337  
338  
339 --[[ 1.5 added this
340 The old way wouldnt leave the channel and join a new one in the same funccall
341 --]]
342 local SW_PendingJoinInfo = {
343 newChan = nil,
344 isPassive = nil,
345 }
346 --[[
347 if isPassive == true that person wont send sync msgs
348 but can listen
349 TODO testing 1.5.3 I noticed some messages do get sent - these are sent through "catch" functions when we
350 send data on a recieved data event, because these are so few not sure if a change is needed
351 --]]
352 function SW_SyncJoin(chanName, isPassive)
353 if tonumber(chanName) then
354 return;
355 end
356 local retName;
357 local id;
358 local oldSynarp;
359  
360 if chanName == nil then return; end
361 SW_Timed_Calls:StopJoinChanPending();
362 SW_Timed_Calls:StopCheckChan();
363 --Stop the pump sending messages
364 SW_SyncChanID = 0;
365  
366 oldSynarp = SW_Settings["SYNARP"];
367 SW_Settings["SYNARP"] = nil;
368 if SW_Settings["SYNCLastChan"] ~= nil then
369 if SW_Settings["SYNCLastChan"] == chanName then
370 -- are we still in this channel?
371 id, _ = GetChannelName(chanName);
372 if id ~= 0 then
373 if SW_Settings["SYNCLastAction"] ~= nil and time() - SW_Settings["SYNCLastAction"] < SW_SyncKeepTime then
374 -- if we get here it was just a repost, for new members to join this chan
375 SW_SyncChanID = id;
376 SW_Settings["SYNARP"] = oldSynarp;
377 return
378 else
379 SW_printStr("Reset on Join LA:"..SW_Settings["SYNCLastAction"].." NOW:"..time());
380 end
381 end
382 else
383 SW_SyncQueue.clearing = true;
384 --SW_DumpResultList(GetChannelList());
385 LeaveChannelByName(SW_Settings["SYNCLastChan"]);
386 end
387 end
388 --SW_DumpResultList(GetChannelList());
389 -- 1.5 leaving and joining while already in 10 channels where 1 is swtats didnt work.
390 SW_PendingJoinInfo.newChan = chanName;
391 SW_PendingJoinInfo.isPassive = isPassive;
392 SW_Timed_Calls:StartJoinChanPending();
393  
394 end
395 function SW_SyncJoinPending()
396 local chanName = SW_PendingJoinInfo.newChan;
397 if chanName == nil then return; end
398  
399 if SW_PendingJoinInfo.isPassive then
400 SW_SyncPassiveMode = isPassive;
401 end
402  
403 SW_SyncQueue.clearing = true;
404 _, retName = JoinChannelByName(chanName);
405 id, _ = GetChannelName(chanName);
406 if id ~= 0 then
407 SW_Settings["SYNCLastChan"] = chanName;
408 SW_SessIDTimer = time();
409 SW_SyncReset(1);
410 SW_Settings["SYNCLastAction"] = time();
411 else
412 -- we werent able to join the chan
413 SW_printStr(SW_SYNC_CHAN_FAIL..chanName, 1);
414 SW_Settings["SYNCLastChan"] = nil;
415 end
416  
417 SW_SyncChanID = id;
418 SW_PendingJoinInfo.newChan = nil;
419 SW_PendingJoinInfo.isPassive = nil;
420 SW_Timed_Calls:StartCheckChan();
421 end
422 function SW_SyncJoinedCheck()
423 local chanName = SW_Settings["SYNCLastChan"];
424 if chanName == nil then
425 return;
426 end
427 if SW_SyncCheckInChan(chanName) then
428 SW_printStr(SW_SYNC_CHAN_JOIN..chanName, 1);
429 local sf =getglobal("SW_BarSyncFrame");
430 -- refresh sync frame
431 if sf:IsVisible() then
432 sf:Hide()
433 sf:Show()
434 end
435 -- be sure we arent paused
436 SW_ToggleRunning(true);
437 -- 1.5.3 show the sync icon
438 SW_BarFrame1_Title_SyncIcon:Show();
439  
440 else
441 SW_printStr(SW_SYNC_CHAN_FAIL..chanName, 1);
442 end
443 end
444 function SW_SyncCheckInChan(chanName)
445 local function Check(...)
446 local i = 1;
447  
448 while arg[i] ~= nil do
449 if arg[i] == chanName then return true; end
450 i = i + 1;
451 end
452 return false;
453 end
454 if Check(GetChannelList()) then
455 return true;
456 else
457 SW_SyncChanID = 0;
458 SW_Settings["SYNCLastChan"] = nil;
459 SW_Settings["SYNARP"] = nil;
460 SW_BarFrame1_Title_SyncIcon:Hide();
461 if chanName then
462 SW_printStr("SW_SyncCheckInChan:False "..chanName);
463 else
464 SW_printStr("SW_SyncCheckInChan:False Name:NIL");
465 end
466 --SW_printStr(debugstack());
467 return false;
468 end
469 end
470 function SW_SyncCheckMsgForChan(msg, who)
471 local chan;
472  
473 _,_,chan = string.find(msg, SW_SYNC_CHAN_REGEX);
474  
475 if chan ~= nil and who~= nil and chan ~= SW_Settings["SYNCLastChan"] then
476 StaticPopupDialogs["SW_JoinCheck"]["SW_toChan"] = chan;
477 StaticPopupDialogs["SW_JoinCheck"]["SW_postedBy"] = who;
478 StaticPopupDialogs["SW_JoinCheck"]["text"] = string.format(SW_SYNC_JOINCHECK_FROM, chan, who).."\n"..SW_SYNC_JOINCHECK_INFO;
479 StaticPopup_Show ("SW_JoinCheck");
480  
481 end
482 end
483  
484 function SW_SyncSplitMsg(msg)
485  
486 local t = {};
487 local function helper(line) table.insert(t, line); end
488 helper((string.gsub(msg, "(.-)%"..SW_SyncQueue.sep, helper)))
489  
490 return t
491 end
492  
493 function SW_SyncCheckAlive()
494 local now = time();
495 for k,v in pairs(SW_S_DetailsSynced) do
496 if v["LI"] ~= nil then
497 if now - v["LI"] > SW_LITimerDead then
498 v["LI"] = nil;
499 end
500 end
501 end
502  
503 if SW_SyncPassiveMode then return; end
504 if SW_S_DetailsSynced[SW_SELF_STRING] == nil or
505 SW_S_DetailsSynced[SW_SELF_STRING]["LI"] == nil or
506 time() - SW_S_DetailsSynced[SW_SELF_STRING]["LI"] > (SW_LITimerDead - 200) then
507  
508 SW_SyncQueue:PushSWInfo("LI");
509 end
510 end
511 function SW_SyncHandleMsg(msg, from)
512 local pre;
513  
514 --[[ this will inject even more wrong people if sombody is drunk.. (S->Sh) but
515 most of the times people use filters, group, evergroup npc etc
516 so these drop out anyways in the display
517 but a lot of the info is most likely valid
518 also this will suppress most unexpected ident msgs if somebody is drunk
519 --]]
520 if SLURRED_SPEECH ~= nil then
521 _,_,pre = string.find(msg, SW_DrunkRegEx)
522 if pre ~= nil then
523 --SW_printStr(msg.."==>"..pre);
524 msg = pre;
525 end
526 end
527 local msgs = SW_SyncSplitMsg(msg);
528 SW_Settings["SYNCLastAction"] = time();
529 local v1,vx,vs,vi,v2,v3,vals,ident, tmpInt, iCount, sCount;
530 --handels a single Sync Msg
531 for __,oneLine in ipairs(msgs) do
532 _,_,v1,vx,vs,vi,v2,v3 = string.find(oneLine, "^(%d+) (%d+) (%d+) (%d+) (.-) (.+)");
533 --_,_,v1,v2,v3 = string.find(oneLine, "^(%d+) (.-) (.+)");
534 if v1==nil or vx==nil or vs==nil or vi==nil or v2==nil or v3==nil then -- another wierd one that happens very rarely
535 -- hmm this could happen if somebody types normal chat messages into the SyncChannel
536 SW_printStr("SW_SyncHandleMsg NIL value FROM: "..from.." in Msg:");
537 SW_printStr(oneLine);
538 return;
539 end
540 vx = tonumber(vx);
541 vs = tonumber(vs);
542 vi = tonumber(vi);
543  
544 vals = {};
545 for info in string.gfind(v3, "[^~]+") do
546 table.insert(vals,info);
547 end
548 if table.getn(vals) ~= vs+vi then
549 SW_printStr("SW_SyncHandleMsg unexpected argument count FROM: "..from.." in Msg:");
550 SW_printStr(oneLine);
551 return;
552 end
553  
554 ident = SW_SyncPepper[v2];
555 if ident == nil then
556 SW_printStr("SW_SyncHandleMsg unexpected type FROM: "..from.." in Msg:");
557 SW_printStr(oneLine);
558 return;
559 end
560 sCount=0;
561 iCount=0;
562 for i,v in ipairs(vals) do
563 tmpInt = tonumber(v);
564 if tmpInt == nil then
565 sCount = sCount+1;
566 else
567 iCount=iCount+1;
568 vals[i] = tmpInt;
569 ident = ident + tmpInt;
570 end
571 end
572  
573 if sCount ~= vs or iCount ~= vi then
574 SW_printStr("SW_SyncHandleMsg type missmatch FROM: "..from.." in Msg:");
575 SW_printStr(oneLine);
576 return;
577 end
578 -- can happen while leaving channel
579 if SW_Settings["SYNCLastChan"] == nil then
580 return;
581 end
582 tmpInt = math.floor(math.sqrt(ident * string.len(SW_Settings["SYNCLastChan"]))) * 1000;
583 ident = math.floor(1000 * math.sqrt(ident * string.len(SW_Settings["SYNCLastChan"])));
584 if ident-tmpInt ~= vx then
585 SW_printStr("SW_SyncHandleMsg unexpected ident FROM: "..from.." in Msg:");
586 SW_printStr(oneLine);
587 return;
588 end
589  
590 -- ignore "old" messages
591 if tonumber(v1) < SW_SyncSessionID then
592  
593 return;
594 end
595 -- 1.4.2 chganged reset logic
596 if tonumber(v1) > SW_SyncSessionID then
597 if v2 == "RE" then
598 SW_SyncReset(v1, from);
599 else
600 SW_SyncReset(v1);
601 end
602 else
603 if SW_S_DetailsSynced[from] == nil then
604 SW_S_DetailsSynced[from] = {};
605 end
606 SW_S_DetailsSynced[from]["LI"] = time();
607 if v2 ~= "RE" then -- if == and RE we issued it and already did reset
608 if SW_SyncMsgs[v2] ~= nil then
609 SW_SyncMsgs[v2](vals, from);
610 end
611 end
612 end
613  
614 end
615 end
616  
617 function SW_GetValPair(name, subItem, S)
618 if S == nil then return nil; end
619 if S[name] == nil then --[[SW_printStr("NILCRAP "..name.." "..subItem);--]] return 0,0; end
620 if S[name][subItem] == nil then return 0,0; end
621  
622 return S[name][subItem][1],S[name][subItem][2];
623 end
624 function SW_SetValPair(name, subItem, S, v1, v2)
625 if S == nil then return nil; end
626 if S[name] == nil then S[name]={}; end
627 if S[name][subItem] == nil then S[name][subItem] = {}; end
628 S[name][subItem][1] = v1;
629 S[name][subItem][2] = v2;
630 end
631 function SW_GetVal(name, subItem, S)
632 if S == nil then return nil; end
633 if S[name] == nil then return 0; end
634 if S[name][subItem] == nil then return 0; end
635  
636 return S[name][subItem];
637 end
638 function SW_SetVal(name, subItem, S, v)
639 if S == nil then return nil; end
640 if S[name] == nil then S[name]={}; end
641  
642 S[name][subItem] = v;
643  
644 end
645 function SW_SyncDo()
646 if SW_Settings["SYNCLastChan"] == nil and SW_SyncChanID ==0 then
647 return;
648 end
649 if not SW_SyncCheckInChan(SW_Settings["SYNCLastChan"]) then
650 return;
651 end
652 if SW_SyncPassiveMode then return; end
653  
654 SW_SyncDoOne(SW_SELF_STRING, true);
655 SW_SyncDoHeal(SW_SELF_STRING, true);
656 SW_SyncDoMana();
657  
658 local SW_SyncP = 0;
659  
660 local rnd;
661 local peerCount =0;
662 for k,v in pairs(SW_S_DetailsSynced) do
663 if SW_S_DetailsSynced[k]["LI"] ~= nil then
664 peerCount = peerCount +1;
665 end
666 end
667 --auto% when to sync
668 if peerCount > 5 then
669 SW_SyncP = math.ceil( (100 / peerCount) / 2 );
670 else
671 -- nonsense to post when alone but i use it for testing
672 SW_SyncP = 10;
673 end
674  
675 for k,v in pairs(SW_S_Details) do
676 rnd = math.random(100);
677  
678 if k ~= SW_SELF_STRING and rnd <= SW_SyncP then
679 if SW_S_DetailsSynced[k] == nil then
680 SW_SyncDoOne(k, false);
681 else
682 if SW_S_DetailsSynced[k]["LI"] == nil then
683 SW_SyncDoOne(k, false);
684 end
685 end
686 end
687 end
688 for k,v in pairs(SW_S_Healed) do
689 rnd = math.random(100);
690 if k ~= SW_SELF_STRING and rnd <= SW_SyncP then
691 if SW_S_HealedSynced[k] == nil then
692 SW_SyncDoHeal(k, false);
693 else
694 -- only tracking "alive" in SW_S_DetailsSynced
695 if SW_S_DetailsSynced[k] == nil or SW_S_DetailsSynced[k]["LI"] == nil then
696 SW_SyncDoHeal(k, false);
697 end
698 end
699 end
700 end
701 for k,v in pairs(SW_PetInfo["PET_OWNER"]) do
702 rnd = math.random(100);
703  
704 if rnd <= SW_SyncP or (v["currentOwners"] and v["currentOwners"][SW_SELF_STRING]) then
705 SW_SyncDoOnePet(k);
706 end
707 end
708 for k,v in pairs(SW_PetInfo["OWNER_PET"]) do
709 rnd = math.random(100);
710  
711 if rnd <= SW_SyncP or k == SW_SELF_STRING then
712 SW_SyncDoOnePetOwner(k);
713 end
714 end
715 for k,v in pairs(SW_S_SpellInfo) do
716 rnd = math.random(100);
717 if rnd <= SW_SyncP or k == SW_SELF_STRING then
718 SW_SyncDoOneDecurseCount(k);
719 end
720 end
721 end
722  
723 -- only do self
724 function SW_SyncDoMana()
725 if SW_S_ManaUsage ~= nil and SW_S_ManaUsage[SW_SELF_STRING] ~= nil then
726  
727 local v = SW_S_ManaUsage[SW_SELF_STRING];
728 if v[1] > 0 or v[2] > 0 then
729 if SW_S_LastManaSent[1] < v[1] or SW_S_LastManaSent[2] < v[2] or SW_S_LastManaSent[3] < v[3] then
730 SW_S_LastManaSent[1] = v[1];
731 SW_S_LastManaSent[2] = v[2];
732 SW_S_LastManaSent[3] = v[3];
733 SW_SyncQueue:PushSWInfo("MI", {SW_ManaAfterDrop[1] + v[1],SW_ManaAfterDrop[2] + v[2],SW_ManaAfterDrop[3] + v[3]});
734 end
735 end
736 end
737 end
738 function SW_SyncDoHeal(name, isSelf)
739 local hi = SW_S_Healed[name];
740 if hi == nil then return; end
741  
742 local hiSync = SW_S_HealedSynced[name];
743 if hiSync == nil and time() - SW_StartupTime < SW_SyncIgnoreNil then
744 return;
745 end
746 for k,v in hi do
747 if hiSync == nil or hiSync[k] == nil or v > hiSync[k] then
748 if isSelf then
749 SW_SyncQueue:PushSWInfo("HIS", {k, v});
750 else
751 SW_SyncQueue:PushSWInfo("HIO", {name, k, v});
752 end
753 end
754 end
755 end
756  
757 function SW_SyncDoOne(name, isSelf)
758 local doneDmg, doneHeal = SW_GetValPair(name, SW_PRINT_ITEM_TOTAL_DONE, SW_S_Details);
759 local gotDmg, gotHeal = SW_GetValPair(name, SW_PRINT_ITEM_RECIEVED, SW_S_Details);
760 local doneDmgS, doneHealS = SW_GetValPair(name, SW_PRINT_ITEM_TOTAL_DONE, SW_S_DetailsSynced);
761 local gotDmgS, gotHealS = SW_GetValPair(name, SW_PRINT_ITEM_RECIEVED, SW_S_DetailsSynced);
762  
763 SW_SyncDoOneDeathCount(name);
764  
765 if doneDmg > doneDmgS or doneHeal > doneHealS or
766 gotDmg > gotDmgS or gotHeal > gotHealS then
767 if isSelf then
768 SW_SyncQueue:PushSWInfo("SI", {doneDmg, doneHeal, gotDmg, gotHeal});
769 else
770 if time() - SW_StartupTime < SW_SyncIgnoreNil then
771 if doneDmgS == 0 and doneHealS == 0 and gotDmgS == 0 and gotHealS == 0 then
772 return;
773 end
774 end
775 SW_SyncQueue:PushSWInfo("OI", {name, doneDmg, doneHeal, gotDmg, gotHeal});
776 end
777 end
778 end
779 function SW_SyncDoOneDeathCount(name)
780 local syDeaths = SW_DCSynced[name];
781 if syDeaths == nil then
782 syDeaths = 0;
783 end
784 if time() - SW_StartupTime < SW_SyncIgnoreNil then
785 if syDeaths == 0 then
786 return;
787 end
788 end
789 local tmpVal = SW_S_Details[name];
790 if tmpVal ~= nil and tmpVal[SW_PRINT_ITEM_DEATHS] ~= nil then
791 tmpVal = tmpVal[SW_PRINT_ITEM_DEATHS];
792 if tmpVal > syDeaths then
793 SW_SyncQueue:PushSWInfo("DC", {name, tmpVal, math.random(100)});
794 end
795 end
796 end
797 function SW_SyncDeathCount(data, from)
798 local name, newDC, id = unpack(data);
799 local syDeaths = SW_DCSynced[name];
800 if syDeaths == nil or newDC > syDeaths then
801 SW_DCSynced[name] = newDC;
802 end
803 syDeaths = SW_DCSynced[name];
804 local tmpVal = SW_S_Details[name];
805 if tmpVal ~= nil then
806 if tmpVal[SW_PRINT_ITEM_DEATHS] == nil or tmpVal[SW_PRINT_ITEM_DEATHS] < syDeaths then
807 tmpVal[SW_PRINT_ITEM_DEATHS] = syDeaths;
808 end
809 end
810  
811 if SW_Settings["EI_ShowSync"] ~= nil then
812 SW_Event_Channel:AddMessage("Info from "..from.." for DeathCount of "..name..": "..newDC);
813 end
814 end
815 function SW_SyncDoOneDecurseCount(name)
816 local syDecs = SW_DecurseCSynced[name];
817 if syDecs == nil then
818 syDecs = 0;
819 end
820  
821 if time() - SW_StartupTime < SW_SyncIgnoreNil then
822 if syDecs == 0 then
823 return;
824 end
825 end
826  
827 local tmpVal = SW_S_SpellInfo[name];
828 if tmpVal ~= nil and tmpVal[SW_DECURSEDUMMY] ~= nil and tmpVal[SW_DECURSEDUMMY]["total"] ~= nil then
829 tmpVal = tmpVal[SW_DECURSEDUMMY]["total"];
830 if tmpVal~=nil and tmpVal > syDecs then
831 SW_SyncQueue:PushSWInfo("DCC", {name, tmpVal, math.random(100)});
832 end
833 end
834  
835 end
836 function SW_SyncDecurseCount(data, from)
837 local name, newDCC, id = unpack(data);
838 local syDecs = SW_DecurseCSynced[name];
839 if syDecs == nil or newDCC > syDecs then
840 SW_DecurseCSynced[name] = newDCC;
841 end
842 syDecs = SW_DecurseCSynced[name];
843 local tmpVal;
844 if SW_S_SpellInfo[name] == nil then
845 SW_S_SpellInfo[name] = {};
846 end
847 if SW_S_SpellInfo[name][SW_DECURSEDUMMY] == nil then
848 SW_S_SpellInfo[name][SW_DECURSEDUMMY] = {};
849 end
850 tmpVal = SW_S_SpellInfo[name][SW_DECURSEDUMMY];
851 if tmpVal["total"] == nil then
852 tmpVal["total"] = 0;
853 end
854  
855 if tmpVal["total"] < syDecs then
856 tmpVal["total"] = syDecs;
857 end
858  
859 if SW_Settings["EI_ShowSync"] ~= nil then
860 SW_Event_Channel:AddMessage("Info from "..from.." for DecurseCount of "..name..": "..newDCC);
861 end
862 end
863  
864 function SW_SyncDoOnePetOwner(name)
865 local doneDmg, doneHeal = SW_GetValPair(name, SW_PRINT_ITEM_TOTAL_DONE, SW_PetInfo["OWNER_PET"]);
866 local gotDmg, gotHeal = SW_GetValPair(name, SW_PRINT_ITEM_RECIEVED, SW_PetInfo["OWNER_PET"]);
867 local doneDmgS, doneHealS = SW_GetValPair(SW_PETOWNER..name, SW_PRINT_ITEM_TOTAL_DONE, SW_S_DetailsSynced);
868 local gotDmgS, gotHealS = SW_GetValPair(SW_PETOWNER..name, SW_PRINT_ITEM_RECIEVED, SW_S_DetailsSynced);
869  
870 if doneDmg > doneDmgS or doneHeal > doneHealS or
871 gotDmg > gotDmgS or gotHeal > gotHealS then
872 if time() - SW_StartupTime < SW_SyncIgnoreNil then
873 if doneDmgS == 0 and doneHealS == 0 and gotDmgS == 0 and gotHealS == 0 then
874 return;
875 end
876 end
877 SW_SyncQueue:PushSWInfo("PO", {name, doneDmg, doneHeal, gotDmg, gotHeal});
878 end
879 end
880  
881 function SW_SyncDoOnePet(name)
882 local doneDmg, doneHeal = SW_GetValPair(name, SW_PRINT_ITEM_TOTAL_DONE, SW_PetInfo["PET_OWNER"]);
883 local gotDmg, gotHeal = SW_GetValPair(name, SW_PRINT_ITEM_RECIEVED, SW_PetInfo["PET_OWNER"]);
884 local doneDmgS, doneHealS = SW_GetValPair(SW_PET..name, SW_PRINT_ITEM_TOTAL_DONE, SW_S_DetailsSynced);
885 local gotDmgS, gotHealS = SW_GetValPair(SW_PET..name, SW_PRINT_ITEM_RECIEVED, SW_S_DetailsSynced);
886  
887 if doneDmg > doneDmgS or doneHeal > doneHealS or
888 gotDmg > gotDmgS or gotHeal > gotHealS then
889 if time() - SW_StartupTime < SW_SyncIgnoreNil then
890 if doneDmgS == 0 and doneHealS == 0 and gotDmgS == 0 and gotHealS == 0 then
891 return;
892 end
893 end
894 SW_SyncQueue:PushSWInfo("PI", {name, doneDmg, doneHeal, gotDmg, gotHeal});
895 end
896 end
897 function SW_SyncPetOwner(data, from)
898 local name, doneDmgS, doneHealS, gotDmgS, gotHealS = unpack(data);
899 local syncName = SW_PETOWNER..name;
900  
901  
902 local doneDmg, doneHeal = SW_GetValPair(name, SW_PRINT_ITEM_TOTAL_DONE, SW_PetInfo["OWNER_PET"]);
903 local gotDmg, gotHeal = SW_GetValPair(name, SW_PRINT_ITEM_RECIEVED, SW_PetInfo["OWNER_PET"]);
904  
905 local doneDmgSync, doneHealSync = SW_GetValPair(syncName, SW_PRINT_ITEM_TOTAL_DONE, SW_S_DetailsSynced);
906 local gotDmgSync, gotHealSync = SW_GetValPair(syncName, SW_PRINT_ITEM_RECIEVED, SW_S_DetailsSynced);
907  
908  
909  
910 if doneDmgS > doneDmgSync or doneHealS > doneHealSync then
911 SW_SetValPair(syncName, SW_PRINT_ITEM_TOTAL_DONE, SW_S_DetailsSynced, doneDmgS, doneHealS);
912 end
913 if gotDmgS > gotDmgSync or gotHealS > gotHealSync then
914 SW_SetValPair(syncName, SW_PRINT_ITEM_RECIEVED, SW_S_DetailsSynced, gotDmgS, gotHealS);
915 end
916  
917 local v1, v2;
918 if doneDmgS > doneDmg then v1 = doneDmgS; else v1 = doneDmg; end
919 if doneHealS > doneHeal then v2 = doneHealS; else v2 = doneHeal; end
920 SW_SetValPair(name, SW_PRINT_ITEM_TOTAL_DONE, SW_PetInfo["OWNER_PET"], v1, v2);
921  
922 if gotDmgS > gotDmg then v1 = gotDmgS; else v1 = gotDmg; end
923 if gotHealS > gotHeal then v2 = gotHealS; else v2 = gotHeal; end
924 SW_SetValPair(name, SW_PRINT_ITEM_RECIEVED, SW_PetInfo["OWNER_PET"], v1, v2);
925  
926 if SW_Settings["EI_ShowSync"] ~= nil then
927 SW_Event_Channel:AddMessage("Info from "..from.." for PETOWNER "..name.." "..doneDmgS.." "..doneHealS.." "..gotDmgS.." "..gotHealS);
928 end
929  
930 end
931  
932 function SW_SyncPetInfo(data, from)
933 local name, doneDmgS, doneHealS, gotDmgS, gotHealS = unpack(data);
934 local syncName = SW_PET..name;
935  
936  
937 local doneDmg, doneHeal = SW_GetValPair(name, SW_PRINT_ITEM_TOTAL_DONE, SW_PetInfo["PET_OWNER"]);
938 local gotDmg, gotHeal = SW_GetValPair(name, SW_PRINT_ITEM_RECIEVED, SW_PetInfo["PET_OWNER"]);
939  
940 local doneDmgSync, doneHealSync = SW_GetValPair(syncName, SW_PRINT_ITEM_TOTAL_DONE, SW_S_DetailsSynced);
941 local gotDmgSync, gotHealSync = SW_GetValPair(syncName, SW_PRINT_ITEM_RECIEVED, SW_S_DetailsSynced);
942  
943  
944  
945 if doneDmgS > doneDmgSync or doneHealS > doneHealSync then
946 SW_SetValPair(syncName, SW_PRINT_ITEM_TOTAL_DONE, SW_S_DetailsSynced, doneDmgS, doneHealS);
947 end
948 if gotDmgS > gotDmgSync or gotHealS > gotHealSync then
949 SW_SetValPair(syncName, SW_PRINT_ITEM_RECIEVED, SW_S_DetailsSynced, gotDmgS, gotHealS);
950 end
951  
952 local v1, v2;
953 if doneDmgS > doneDmg then v1 = doneDmgS; else v1 = doneDmg; end
954 if doneHealS > doneHeal then v2 = doneHealS; else v2 = doneHeal; end
955 SW_SetValPair(name, SW_PRINT_ITEM_TOTAL_DONE, SW_PetInfo["PET_OWNER"], v1, v2);
956  
957 if gotDmgS > gotDmg then v1 = gotDmgS; else v1 = gotDmg; end
958 if gotHealS > gotHeal then v2 = gotHealS; else v2 = gotHeal; end
959 SW_SetValPair(name, SW_PRINT_ITEM_RECIEVED, SW_PetInfo["PET_OWNER"], v1, v2);
960  
961 if SW_Settings["EI_ShowSync"] ~= nil then
962 SW_Event_Channel:AddMessage("Info from "..from.." for PET "..name.." "..doneDmgS.." "..doneHealS.." "..gotDmgS.." "..gotHealS);
963 end
964  
965 end
966  
967 function SW_SyncBasicInfo(data, from, isSelf)
968 local doneDmgS, doneHealS, gotDmgS, gotHealS = unpack(data);
969 local isSelfStr ="";
970 local buffedDmg, buffedHeal;
971  
972 if from == nil then
973 SW_Event_Channel:AddMessage("From:NIL");
974 return;
975 end
976 if isSelf then
977 isSelfStr = " IsSelf ";
978 else
979 isSelfStr = " IsOther ";
980 end
981 if doneDmgS == nil then
982 SW_Event_Channel:AddMessage("From:"..from..isSelfStr.."doneDmgS == NIL: "..data);
983 return;
984 elseif doneHealS == nil then
985 SW_Event_Channel:AddMessage("From:"..from..isSelfStr.."doneHealS == NIL: "..data);
986 return;
987 elseif gotDmgS == nil then
988 SW_Event_Channel:AddMessage("From:"..from..isSelfStr.."gotDmgS == NIL: "..data);
989 return;
990 elseif gotHealS == nil then
991 SW_Event_Channel:AddMessage("From:"..from..isSelfStr.."gotHealS == NIL: "..data);
992 return;
993 end
994  
995 local doneDmg, doneHeal = SW_GetValPair(from, SW_PRINT_ITEM_TOTAL_DONE, SW_S_Details);
996 local gotDmg, gotHeal = SW_GetValPair(from, SW_PRINT_ITEM_RECIEVED, SW_S_Details);
997 --check here if somebody came back after a "reset" (he was disconnected to long)
998 if isSelf and from ~= SW_SELF_STRING and (doneDmgS < doneDmg or doneHealS < doneHeal ) then
999 -- this will trigger a message from every player with the addon installed
1000 -- maybe find a better way (but this doesnt happen on a regular basis)
1001 -- also the first few "ticks" of selfinfo are lost but ist very little compared to total stats
1002 -- and maybe somebody else even got those msgs and we ar totally correct
1003 --RC5 Changed this.. generated a LOT of chat spam only issue an update like this if its heihger then SW_ValBuffer %
1004 -- could happen because of the chat send delay + chat delay, somebody sent info
1005 -- that was correct but it arrived 2 seconds later and this would trigger this aswell
1006  
1007 buffedDmg = ((doneDmgS/100) * SW_ValBuffer) + doneDmgS;
1008 buffedHeal = ((doneHealS/100) * SW_ValBuffer) + doneHealS;
1009 if buffedDmg < doneDmg or buffedHeal < doneHeal then
1010 if not SW_SyncPassiveMode then
1011 --1.5.3 after a reset this would generate unneded msgs
1012 -- added a delta val buffer depending on the level
1013 if SW_Friends[from] ~= nil and SW_Friends[from]["L"] ~= nil and SW_Friends[from]["L"] > 0 then
1014 local minVal = SW_Friends[from]["L"] * 100;
1015 if ((doneDmgS + minVal) < doneDmg) or ((doneHealS + minVal) < doneHeal) then
1016 SW_SyncQueue:PushSWInfo("OI", {from, doneDmg, doneHeal, gotDmg, gotHeal});
1017 end
1018 else
1019 -- still have this here for sync to work as expected for people that aren't grouped
1020 SW_SyncQueue:PushSWInfo("OI", {from, doneDmg, doneHeal, gotDmg, gotHeal});
1021 end
1022 end
1023 end
1024 return;
1025 end
1026  
1027 local doneDmgSync, doneHealSync = SW_GetValPair(from, SW_PRINT_ITEM_TOTAL_DONE, SW_S_DetailsSynced);
1028 local gotDmgSync, gotHealSync = SW_GetValPair(from, SW_PRINT_ITEM_RECIEVED, SW_S_DetailsSynced);
1029  
1030 local topDelta =0;
1031 if isSelf and (doneDmgSync > 0) then
1032 topDelta = doneDmgS - doneDmgSync;
1033 if SW_Sync_MsgTrack[from]["TOPDELTAD"] < topDelta then
1034 SW_Sync_MsgTrack[from]["TOPDELTAD"] = topDelta;
1035 end
1036 end
1037 if isSelf and (doneHealSync > 0) then
1038 topDelta = doneHealS - doneHealSync;
1039 if SW_Sync_MsgTrack[from]["TOPDELTAH"] < topDelta then
1040 SW_Sync_MsgTrack[from]["TOPDELTAH"] = topDelta;
1041 end
1042 end
1043  
1044 --0.98 no need to update lower info in synced
1045 if doneDmgS > doneDmgSync or doneHealS > doneHealSync then
1046 SW_SetValPair(from, SW_PRINT_ITEM_TOTAL_DONE, SW_S_DetailsSynced, doneDmgS, doneHealS);
1047 end
1048 if gotDmgS > gotDmgSync or gotHealS > gotHealSync then
1049 SW_SetValPair(from, SW_PRINT_ITEM_RECIEVED, SW_S_DetailsSynced, gotDmgS, gotHealS);
1050 end
1051  
1052 local v1, v2, sIInced=false;
1053 if doneDmgS > doneDmg then
1054 v1 = doneDmgS;
1055 if isSelf then
1056 SW_Sync_MsgTrack[from]["SI_WAS_NEEDED"] = SW_Sync_MsgTrack[from]["SI_WAS_NEEDED"] + 1;
1057 sIInced=true;
1058 end
1059 else
1060 v1 = doneDmg;
1061 end
1062 if doneHealS > doneHeal then
1063 v2 = doneHealS;
1064 if isSelf and (not sIInced) then
1065 SW_Sync_MsgTrack[from]["SI_WAS_NEEDED"] = SW_Sync_MsgTrack[from]["SI_WAS_NEEDED"] + 1;
1066 sIInced=true;
1067 end
1068 else
1069 v2 = doneHeal;
1070 end
1071  
1072 SW_SetValPair(from, SW_PRINT_ITEM_TOTAL_DONE, SW_S_Details, v1, v2);
1073  
1074 if gotDmgS > gotDmg then v1 = gotDmgS; else v1 = gotDmg; end
1075 if gotHealS > gotHeal then v2 = gotHealS; else v2 = gotHeal; end
1076  
1077 -- 1.5.3 raid per second
1078 -- an SI with dmg is valid
1079 if isSelf and (doneDmgS > doneDmg) then
1080 SW_RPS:validEvent();
1081 end
1082 SW_SetValPair(from, SW_PRINT_ITEM_RECIEVED, SW_S_Details, v1, v2);
1083  
1084 if SW_Settings["EI_ShowSync"] ~= nil then
1085 if isSelf then
1086 SW_Event_Channel:AddMessage("SelfInfo for "..from.." "..doneDmgS.." "..doneHealS.." "..gotDmgS.." "..gotHealS);
1087 else
1088 SW_Event_Channel:AddMessage("Info for "..from.." "..doneDmgS.." "..doneHealS.." "..gotDmgS.." "..gotHealS);
1089 end
1090 end
1091  
1092 end
1093  
1094 function SW_checkSIOI()
1095 local vals = {};
1096 for k, v in pairs (SW_Sync_MsgTrack) do
1097 if v["OI_UPDATE_SI"] > 0 then
1098 table.insert(vals, {k, v["OI_UPDATE_SI"]});
1099 end
1100 end
1101 table.sort(vals,
1102 function(a,b)
1103 return a[2] > b[2];
1104 end);
1105 return vals;
1106 end
1107 function SW_checkSINeeded()
1108 local vals = {};
1109 for k, v in pairs (SW_Sync_MsgTrack) do
1110 if v["SI_WAS_NEEDED"] > 0 then
1111 table.insert(vals, {k, v["SI_WAS_NEEDED"]});
1112 end
1113 end
1114 table.sort(vals,
1115 function(a,b)
1116 return a[2] > b[2];
1117 end);
1118 return vals;
1119 end
1120 function SW_updateMsgTrack(from, isOI, data)
1121 if SW_Sync_MsgTrack[from] == nil then
1122 SW_Sync_MsgTrack[from] = {["OI"] = 0, ["SI"] = 0, ["OI_UPDATE_SI"] = 0, ["SI_WAS_NEEDED"] = 0, ["TOPDELTAD"] = 0, ["TOPDELTAH"] = 0};
1123 end
1124 if isOI then
1125 if SW_S_DetailsSynced[ data[1] ] and SW_S_DetailsSynced[ data[1] ]["LI"] ~= nil then
1126 SW_Sync_MsgTrack[from]["OI_UPDATE_SI"] = SW_Sync_MsgTrack[from]["OI_UPDATE_SI"] + 1;
1127 else
1128 SW_Sync_MsgTrack[from]["OI"] = SW_Sync_MsgTrack[from]["OI"] + 1;
1129 end
1130 else
1131 SW_Sync_MsgTrack[from]["SI"] = SW_Sync_MsgTrack[from]["SI"] + 1;
1132 end
1133 end
1134 function SW_SyncSelfInfo(data, from)
1135 SW_updateMsgTrack(from, false, data);
1136 SW_SyncBasicInfo(data, from, true);
1137 end
1138 function SW_SyncOtherInfo(data, from)
1139 --local _,_,nameFrom, restData = string.find(data, "^~(.-)~ (.+)");
1140 --SW_SyncBasicInfo(restData, nameFrom, false);
1141 SW_updateMsgTrack(from, true, data);
1142  
1143 local name = data[1];
1144 table.remove(data, 1);
1145 SW_SyncBasicInfo(data, name, false);
1146 end
1147 function SW_SyncSendARP(allow)
1148 if UnitInRaid("player") and not (IsRaidLeader() or IsRaidOfficer()) then
1149 return;
1150 end
1151 if allow then
1152 SW_SyncQueue:PushSWInfo("ARP", {"true", math.random(100)});
1153 else
1154 SW_SyncQueue:PushSWInfo("ARP", {"false", math.random(100)});
1155 end
1156 end
1157 function SW_SyncAllowReport(data, from)
1158 if SW_Settings["EI_ShowSync"] ~= nil then
1159 SW_Event_Channel:AddMessage("Allow Report "..data[1].." from "..from);
1160 end
1161 if data[1] == "true" then
1162 SW_Settings["SYNARP"] = true;
1163 else
1164 SW_Settings["SYNARP"] = nil;
1165 end
1166 end
1167 function SW_SyncManaInfo(data, from)
1168 if from ~= SW_SELF_STRING then
1169 if SW_S_ManaUsage[from] ~= nil then
1170 if data[3] < SW_S_ManaUsage[from][3] then
1171 --the sender dropped, alt+f4d etc.
1172 -- this isn't time critical and we don't want a huge spam when somebody comes back
1173 -- so just make it a 20% chance
1174 local rnd = math.random(100);
1175 if rnd < 20 then
1176 local mu = SW_S_ManaUsage[from];
1177 SW_SyncQueue:PushSWInfo("MIO", {from, mu[1], mu[2], mu[3]});
1178 end
1179 else
1180 SW_S_ManaUsage[from] = {unpack(data)};
1181 end
1182 else
1183 SW_S_ManaUsage[from] = {unpack(data)};
1184 end
1185 end
1186 if SW_Settings["EI_ShowSync"] ~= nil then
1187 SW_Event_Channel:AddMessage("ManaInfo from "..from.." "..data[1].." "..data[2].." "..data[3]);
1188 end
1189 end
1190  
1191 function SW_SyncManaInfoOther(data, from)
1192  
1193 --this happens when we posten a self mana info and somebody in the SyncChannel
1194 -- had a higher value stored, we dropped or alt+f4'd etc
1195 if data[1] == SW_SELF_STRING then
1196 local tp, m1, m2, m3 = unpack(data);
1197 local m1o, m2o, m3o = unpack(SW_ManaAfterDrop);
1198 if m3 > m3o then
1199 SW_ManaAfterDrop = {m1,m2,m3};
1200 end
1201 end
1202 if SW_Settings["EI_ShowSync"] ~= nil then
1203 SW_Event_Channel:AddMessage("ManaInfoOther from "..from.." for "..data[1].." "..data[2].." "..data[3].." "..data[4]);
1204 end
1205  
1206 end
1207 function SW_SyncAlive(data, from)
1208 if SW_Settings["EI_ShowSync"] ~= nil then
1209 SW_Event_Channel:AddMessage("LI from "..from);
1210 end
1211  
1212 -- nothing really to do here
1213 end
1214  
1215 -- 0.98 heal info details (who healed who)
1216 function SW_SyncHealInfo(healer, healTarget, amount, isSelf)
1217  
1218 healed = SW_GetVal(healer, healTarget, SW_S_Healed);
1219 healedSync = SW_GetVal(healer, healTarget, SW_S_HealedSynced);
1220  
1221 --the person posting self info dropped
1222 if isSelf and healer ~= SW_SELF_STRING and amount < healed then
1223 --SW_SyncQueue:Push(SW_SyncSessionID.." HIO ~"..healer.."~ ~"..healTarget.."~ "..healed);
1224 if ((amount/100) * SW_ValBuffer) + amount < healed then
1225 SW_SyncQueue:PushSWInfo("HIO", {healer, healTarget, healed});
1226 end
1227 return;
1228 end
1229  
1230 if amount > healedSync then
1231 SW_SetVal(healer, healTarget, SW_S_HealedSynced, amount);
1232 end
1233 if healed < amount then
1234 SW_SetVal(healer, healTarget, SW_S_Healed, amount);
1235 end
1236 if SW_Settings["EI_ShowSync"] ~= nil then
1237 if isSelf then
1238 SW_Event_Channel:AddMessage("SelfInfo "..healer.." healed "..healTarget.." "..amount);
1239 else
1240 SW_Event_Channel:AddMessage("Info "..healer.." healed "..healTarget.." "..amount);
1241 end
1242 end
1243 end
1244 function SW_SyncSendLeave()
1245 if SW_Settings["SYNCLastChan"] ~= nil then
1246 SW_SyncQueue:Clear();
1247 SW_SyncQueue:PushSWInfo("LS");
1248 SW_SyncLeavingChannel = true;
1249 end
1250 end
1251 function SW_SyncHealInfoOther(data, from)
1252 local nameFrom, nameTo, amount = unpack(data);
1253  
1254 SW_SyncHealInfo(nameFrom, nameTo, amount, false);
1255 end
1256 function SW_SyncHealInfoSelf(data, from)
1257 local nameTo, amount = unpack(data);
1258 SW_SyncHealInfo(from, nameTo, amount, true);
1259 end
1260 function SW_SyncRequestFullSync()
1261 --SW_SyncQueue:Push(SW_SyncSessionID.." FS "..SW_SyncSessionID);
1262 SW_SyncQueue:PushSWInfo("FS");
1263 end
1264 --0.98b added full sync
1265 --1.5 removed the console sommand to acces this
1266 -- it's just nbot needed in the current form
1267 function SW_SyncFullSync(nop, from)
1268 -- A full sync.. never ever do in fight.....
1269 if from == SW_SELF_STRING then
1270 --this works but not sure if i want it
1271 -- idea is that the requestor sends out all his info
1272 SW_S_DetailsSynced = {};
1273 SW_S_HealedSynced = {};
1274 end
1275 for k,v in pairs(SW_S_Details) do
1276 if k == SW_SELF_STRING then
1277 SW_SyncDoOne(k, true);
1278 else
1279 SW_SyncDoOne(k, false);
1280 end
1281 end
1282 for k,v in pairs(SW_S_Healed) do
1283 if k == SW_SELF_STRING then
1284 SW_SyncDoHeal(k, true);
1285 else
1286 SW_SyncDoHeal(k, false);
1287 end
1288 end
1289 end
1290 function SW_SyncLeave(data, from)
1291 if SW_S_DetailsSynced[from] ~= nil then
1292 SW_S_DetailsSynced[from]["LI"] = nil;
1293 end
1294 end
1295  
1296 function SW_SyncSendRSU(skillName)
1297 SW_SyncQueue:PushSWInfo("RSU", {skillName, math.random(100)});
1298 end
1299 function SW_SyncRequestSkillUsage(data, from)
1300  
1301 if SW_S_SpellInfo[SW_SELF_STRING] ~= nil and SW_S_SpellInfo[SW_SELF_STRING][ data[1] ] ~= nil then
1302 SW_SyncQueue:PushSWInfo("SU", {data[1], SW_S_SpellInfo[SW_SELF_STRING][ data[1] ][1], math.random(100)});
1303 end
1304 if SW_Settings["EI_ShowSync"] ~= nil then
1305 SW_Event_Channel:AddMessage("Request Skill Usage from "..from.." for Skill "..data[1]);
1306 end
1307 end
1308  
1309 function SW_SyncSkillUsage(data, from)
1310 SW_printStr("["..date("%X").."] "..LIGHTYELLOW_FONT_COLOR_CODE..from..FONT_COLOR_CODE_CLOSE.." "..data[1]..":"..RED_FONT_COLOR_CODE..data[2]..FONT_COLOR_CODE_CLOSE);
1311 if SW_Settings["EI_ShowSync"] ~= nil then
1312 SW_Event_Channel:AddMessage("Skill Usage "..from.." for Skill "..data[1]..":"..data[2]);
1313 end
1314 end
1315  
1316 -- added 1.4 version check stuff
1317 function SW_SyncSendRSV()
1318 SW_SyncQueue:PushSWInfo("RSV", {math.random(100)});
1319 end
1320 function SW_SyncRequestVersionCheck(data, from)
1321  
1322 SW_SyncQueue:PushSWInfo("SV", {SW_VERSION, GetLocale(), math.random(100)});
1323 if SW_Settings["EI_ShowSync"] ~= nil then
1324 SW_Event_Channel:AddMessage("Request Version info from "..from);
1325 end
1326 end
1327 function SW_SyncVersionCheck(data, from)
1328 if data[2] ~= nil and tonumber(data[2]) then
1329 SW_printStr("["..date("%X").."] "..from.." "..RED_FONT_COLOR_CODE..data[1]..FONT_COLOR_CODE_CLOSE);
1330 else
1331 SW_printStr("["..date("%X").."] "..from.." "..RED_FONT_COLOR_CODE..data[1]..FONT_COLOR_CODE_CLOSE.." ("..data[2]..")");
1332 end
1333 if SW_Settings["EI_ShowSync"] ~= nil then
1334 SW_Event_Channel:AddMessage("V "..from..": "..data[1].." "..data[2]);
1335 end
1336 end
1337 -- added 1.4 kicking people from the sync chan
1338 -- usefull if somebody left the raid/group and is still playing
1339 function SW_SyncKick(data, from)
1340 if SW_Settings["EI_ShowSync"] ~= nil then
1341 SW_Event_Channel:AddMessage("KICK from "..from.." for: "..data[1]);
1342 end
1343 SW_printStr("["..date("%X").."] KICK from "..from.." for:"..RED_FONT_COLOR_CODE..data[1]..FONT_COLOR_CODE_CLOSE);
1344 if data[1] == SW_SELF_STRING then
1345 SW_SyncSendLeave();
1346 end
1347 end
1348 function SW_SendSyncKick(who)
1349 SW_SyncQueue:PushSWInfo("KI", {who, math.random(100)});
1350 end
1351  
1352 function SW_SyncGetLIs()
1353 local out = {};
1354 local SW_PC = 0;
1355  
1356 for k,v in pairs(SW_S_DetailsSynced) do
1357 if SW_S_DetailsSynced[k]["LI"] ~= nil then
1358 SW_PC = SW_PC +1;
1359 out[k] = 1;
1360 end
1361 end
1362 out["SW_PC"] = SW_PC;
1363 return out;
1364 end
1365  
1366 function SW_SyncInit()
1367 -- use "base 89"
1368 -- had nil problems usinglower base to see if it fixes that
1369 -- turned off compression alltogether for now
1370 --SW_SyncInt:Init(84);
1371  
1372 SW_SyncMsgs ={
1373 ["RE"] = SW_SyncReset,
1374 ["OI"] = SW_SyncOtherInfo,
1375 ["SI"] = SW_SyncSelfInfo,
1376 ["LI"] = SW_SyncAlive,
1377 ["HIO"] = SW_SyncHealInfoOther,
1378 ["HIS"] = SW_SyncHealInfoSelf,
1379 ["FS"] = SW_SyncFullSync,
1380 ["LS"] = SW_SyncLeave,
1381 ["MI"] = SW_SyncManaInfo,
1382 ["MIO"] = SW_SyncManaInfoOther,
1383 ["ARP"] = SW_SyncAllowReport,
1384 ["RSU"] = SW_SyncRequestSkillUsage,
1385 ["SU"] = SW_SyncSkillUsage,
1386 ["RSV"] = SW_SyncRequestVersionCheck,
1387 ["SV"] = SW_SyncVersionCheck,
1388 ["KI"] = SW_SyncKick,
1389 ["PI"] = SW_SyncPetInfo,
1390 ["PO"] = SW_SyncPetOwner,
1391 ["DC"] = SW_SyncDeathCount,
1392 ["IV"] = SW_SyncIssuedVote,
1393 ["IVA"] = SW_SyncIssuedVoteAnswer,
1394 ["VA"] = SW_SyncVoteAnswer,
1395 ["DCC"] = SW_SyncDecurseCount,
1396  
1397 };
1398 SW_SyncPepper ={
1399 ["RE"] = 3985,
1400 ["OI"] = 9724,
1401 ["SI"] = 9967,
1402 ["LI"] = 5391,
1403 ["HIO"] = 8549,
1404 ["HIS"] = 3941,
1405 ["FS"] = 7105,
1406 ["LS"] = 6418,
1407 ["MI"] = 8256,
1408 ["MIO"] = 9601,
1409 ["ARP"] = 4215,
1410 ["RSU"] = 1098,
1411 ["SU"] = 7209,
1412 ["RSV"] = 5780,
1413 ["SV"] = 3009,
1414 ["KI"] = 6105,
1415 ["PI"] = 2193,
1416 ["PO"] = 6623,
1417 ["DC"] = 1043,
1418 ["IV"] = 8312,
1419 ["IVA"] = 3104,
1420 ["VA"] = 8858,
1421 ["DCC"] = 5103,
1422 };
1423  
1424 end