dayzplayerinventory.c 90 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722
  1. //Post event containers
  2. class DeferredEvent
  3. {
  4. InventoryMode m_mode;
  5. bool ReserveInventory(HumanInventory inventory){return true;}
  6. void ClearInventoryReservation(HumanInventory inventory){}
  7. }
  8. class DeferredTakeToDst : DeferredEvent
  9. {
  10. ref InventoryLocation m_src;
  11. ref InventoryLocation m_dst;
  12. void DeferredTakeToDst(InventoryMode mode, notnull InventoryLocation src, notnull InventoryLocation dst)
  13. {
  14. m_mode = mode;
  15. m_src = src;
  16. m_dst = dst;
  17. }
  18. override bool ReserveInventory(HumanInventory inventory)
  19. {
  20. if (!inventory.HasInventoryReservation(m_dst.GetItem(), m_dst))
  21. {
  22. if ( inventory.AddInventoryReservationEx(m_dst.GetItem(), m_dst, GameInventory.c_InventoryReservationTimeoutShortMS) )
  23. {
  24. return true;
  25. }
  26. }
  27. return false;
  28. }
  29. override void ClearInventoryReservation(HumanInventory inventory)
  30. {
  31. inventory.ClearInventoryReservationEx(m_dst.GetItem(), m_dst);
  32. }
  33. }
  34. class DeferredSwapEntities : DeferredEvent
  35. {
  36. EntityAI m_item1;
  37. EntityAI m_item2;
  38. ref InventoryLocation m_dst1;
  39. ref InventoryLocation m_dst2;
  40. void DeferredSwapEntities(InventoryMode mode, notnull EntityAI item1, notnull EntityAI item2, notnull InventoryLocation dst1, notnull InventoryLocation dst2)
  41. {
  42. m_mode = mode;
  43. m_item1 = item1;
  44. m_item2 = item2;
  45. m_dst1 = dst1;
  46. m_dst2 = dst2;
  47. }
  48. override bool ReserveInventory(HumanInventory inventory)
  49. {
  50. if (!inventory.HasInventoryReservation(m_item1, m_dst1) && !inventory.HasInventoryReservation(m_item2, m_dst2))
  51. {
  52. if (inventory.AddInventoryReservationEx(m_item1, m_dst1, GameInventory.c_InventoryReservationTimeoutShortMS))
  53. {
  54. if (inventory.AddInventoryReservationEx(m_item2, m_dst2, GameInventory.c_InventoryReservationTimeoutShortMS))
  55. {
  56. return true;
  57. }
  58. else
  59. {
  60. inventory.ClearInventoryReservationEx(m_item1, m_dst1);
  61. }
  62. }
  63. }
  64. return false;
  65. }
  66. override void ClearInventoryReservation(HumanInventory inventory)
  67. {
  68. inventory.ClearInventoryReservationEx(m_item1, m_dst1);
  69. inventory.ClearInventoryReservationEx(m_item2, m_dst2);
  70. }
  71. }
  72. class DeferredForceSwapEntities : DeferredEvent
  73. {
  74. EntityAI m_item1;
  75. EntityAI m_item2;
  76. ref InventoryLocation m_dst1;
  77. ref InventoryLocation m_dst2;
  78. void DeferredForceSwapEntities(InventoryMode mode, notnull EntityAI item1, notnull EntityAI item2, notnull InventoryLocation dst1, notnull InventoryLocation dst2)
  79. {
  80. m_mode = mode;
  81. m_item1 = item1;
  82. m_item2 = item2;
  83. m_dst1 = dst1;
  84. m_dst2 = dst2;
  85. }
  86. override bool ReserveInventory(HumanInventory inventory)
  87. {
  88. if (!inventory.HasInventoryReservation(m_item1, m_dst1) && !inventory.HasInventoryReservation(m_item2, m_dst2))
  89. {
  90. if (inventory.AddInventoryReservationEx(m_item1, m_dst1, GameInventory.c_InventoryReservationTimeoutShortMS))
  91. {
  92. if (inventory.AddInventoryReservationEx(m_item2, m_dst2, GameInventory.c_InventoryReservationTimeoutShortMS))
  93. {
  94. return true;
  95. }
  96. else
  97. {
  98. inventory.ClearInventoryReservationEx(m_item1, m_dst1);
  99. }
  100. }
  101. }
  102. return false;
  103. }
  104. override void ClearInventoryReservation(HumanInventory inventory)
  105. {
  106. inventory.ClearInventoryReservationEx(m_item1, m_dst1);
  107. inventory.ClearInventoryReservationEx(m_item2, m_dst2);
  108. }
  109. }
  110. class DeferredHandEvent: DeferredEvent
  111. {
  112. ref HandEventBase m_event;
  113. void DeferredHandEvent(InventoryMode mode, HandEventBase e)
  114. {
  115. m_mode = mode;
  116. m_event = e;
  117. }
  118. override bool ReserveInventory(HumanInventory inventory)
  119. {
  120. return m_event.ReserveInventory();
  121. }
  122. override void ClearInventoryReservation(HumanInventory inventory)
  123. {
  124. m_event.ClearInventoryReservation();
  125. }
  126. }
  127. /**
  128. * @class DayZPlayerInventory
  129. **/
  130. class DayZPlayerInventory : HumanInventoryWithFSM
  131. {
  132. ref DeferredEvent m_DeferredEvent = NULL;
  133. ref Timer m_DeferredWeaponTimer = new Timer;
  134. //protected ref HandEventBase m_PostedHandEvent = NULL; /// deferred hand event
  135. protected ref HandEventBase m_DeferredPostedHandEvent = NULL; /// deferred hand event
  136. ref WeaponEventBase m_DeferredWeaponEvent = NULL; /// deferred weapon event
  137. // states with animations
  138. protected ref HandAnimatedTakingFromAtt m_Taking;
  139. protected ref HandAnimatedMovingToAtt m_MovingTo;
  140. protected ref HandAnimatedSwapping m_Swapping;
  141. protected ref HandAnimatedForceSwapping m_FSwapping;
  142. protected ref HandAnimatedForceSwapping_Inst m_FSwappingInst;
  143. void DayZPlayerInventory ()
  144. {
  145. }
  146. DayZPlayer GetDayZPlayerOwner () { return DayZPlayer.Cast(GetInventoryOwner()); }
  147. bool IsAuthoritative()
  148. {
  149. DayZPlayer player;
  150. if (!Class.CastTo(player, GetInventoryOwner()))
  151. {
  152. return false;
  153. }
  154. return (player.GetInstanceType() != DayZPlayerInstanceType.INSTANCETYPE_CLIENT && player.GetInstanceType() != DayZPlayerInstanceType.INSTANCETYPE_REMOTE);
  155. }
  156. bool IsOwner()
  157. {
  158. DayZPlayer player;
  159. if (!Class.CastTo(player, GetInventoryOwner()))
  160. {
  161. return false;
  162. }
  163. return (player.GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_CLIENT || player.GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_AI_SERVER || player.GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_AI_SINGLEPLAYER);
  164. }
  165. bool IsProxy()
  166. {
  167. DayZPlayer player;
  168. if (!Class.CastTo(player, GetInventoryOwner()))
  169. {
  170. return false;
  171. }
  172. return (player.GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_REMOTE || player.GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_AI_REMOTE);
  173. }
  174. override void Init ()
  175. {
  176. if (LogManager.IsInventoryHFSMLogEnable())
  177. {
  178. hndDebugPrint("[hndfsm] Creating DayZPlayer Inventory FSM");
  179. }
  180. CreateStableStates(); // stable states needs to be created first
  181. m_Taking = new HandAnimatedTakingFromAtt(GetManOwner(), null);
  182. m_MovingTo = new HandAnimatedMovingToAtt(GetManOwner(), null);
  183. m_Swapping = new HandAnimatedSwapping(GetManOwner(), null);
  184. m_FSwapping = new HandAnimatedForceSwapping(GetManOwner(), null);
  185. m_FSwappingInst = new HandAnimatedForceSwapping_Inst(GetManOwner(), null);
  186. // events
  187. HandEventBase _fin_ = new HandEventHumanCommandActionFinished;
  188. HandEventBase _abt_ = new HandEventHumanCommandActionAborted;
  189. HandEventBase __T__ = new HandEventTake;
  190. HandEventBase __M__ = new HandEventMoveTo;
  191. HandEventBase __W__ = new HandEventSwap;
  192. //HandEventBase __D__ = new HandEventDropping;
  193. HandEventBase __Xd_ = new HandEventDestroyed;
  194. HandEventBase __F__ = new HandEventForceSwap;
  195. // setup transitions
  196. m_FSM.AddTransition(new HandTransition( m_Empty , __T__, m_Taking, NULL, new HandSelectAnimationOfTakeToHandsEvent(GetManOwner())));
  197. m_FSM.AddTransition(new HandTransition( m_Taking , _fin_, m_Empty, null, new HandGuardNot(new HandGuardHasItemInHands(GetManOwner()))));
  198. m_FSM.AddTransition(new HandTransition( m_Taking , _fin_, m_Equipped, null, null));
  199. m_FSM.AddTransition(new HandTransition( m_Taking , __Xd_, m_Empty, new HandActionDestroyed, new HandGuardHasDestroyedItemInHands(GetManOwner())));
  200. m_Taking.AddTransition(new HandTransition( m_Taking.m_Hide, _abt_, m_Empty));
  201. m_Taking.AddTransition(new HandTransition( m_Taking.m_Show, _abt_, m_Equipped));
  202. m_FSM.AddTransition(new HandTransition( m_Equipped, __M__, m_MovingTo, NULL, new HandSelectAnimationOfMoveFromHandsEvent(GetManOwner())));
  203. m_FSM.AddTransition(new HandTransition( m_MovingTo, __Xd_, m_Empty, new HandActionDestroyed, new HandGuardHasDestroyedItemInHands(GetManOwner())));
  204. m_FSM.AddTransition(new HandTransition( m_MovingTo, _fin_, m_Equipped, null, new HandGuardHasItemInHands(GetManOwner())));
  205. m_FSM.AddTransition(new HandTransition( m_MovingTo, _fin_, m_Empty , null, null));
  206. m_MovingTo.AddTransition(new HandTransition( m_MovingTo.m_Hide, _abt_, m_Equipped));
  207. m_MovingTo.AddTransition(new HandTransition( m_MovingTo.m_Show, _abt_, m_Empty));
  208. m_FSM.AddTransition(new HandTransition( m_Equipped, __W__, m_Swapping, NULL, new HandSelectAnimationOfSwapInHandsEvent(GetManOwner())));
  209. m_FSM.AddTransition(new HandTransition( m_Swapping, __Xd_, m_Empty, new HandActionDestroyed, new HandGuardHasDestroyedItemInHands(GetManOwner())));
  210. m_FSM.AddTransition(new HandTransition( m_Swapping, _fin_, m_Empty, null, new HandGuardNot(new HandGuardHasItemInHands(GetManOwner()))));
  211. m_FSM.AddTransition(new HandTransition( m_Swapping, _fin_, m_Equipped, null, null));
  212. m_FSM.AddTransition(new HandTransition( m_Swapping, _abt_, m_Equipped, null, null));
  213. m_FSM.AddTransition(new HandTransition( m_Equipped, __F__, m_FSwappingInst, NULL, new HandGuardAnd( new HandSelectAnimationOfForceSwapInHandsEvent(GetManOwner()), new HandGuardInstantForceSwap(GetManOwner()) ) ));
  214. m_FSM.AddTransition(new HandTransition(m_FSwappingInst, _fin_, m_Equipped, null, new HandGuardHasItemInHands(GetManOwner())));
  215. m_FSM.AddTransition(new HandTransition(m_FSwappingInst, _fin_, m_Empty, null, null));
  216. m_FSM.AddTransition(new HandTransition(m_FSwappingInst, __Xd_, m_Empty, new HandActionDestroyed, new HandGuardHasDestroyedItemInHands(GetManOwner())));
  217. m_FSM.AddTransition(new HandTransition( m_FSwappingInst, _abt_, m_Equipped, null, null));
  218. m_FSM.AddTransition(new HandTransition( m_Equipped, __F__, m_FSwapping, NULL, new HandSelectAnimationOfForceSwapInHandsEvent(GetManOwner())));
  219. m_FSM.AddTransition(new HandTransition(m_FSwapping, _fin_, m_Equipped, null, new HandGuardHasItemInHands(GetManOwner())));
  220. m_FSM.AddTransition(new HandTransition(m_FSwapping, _fin_, m_Empty, null, null));
  221. m_FSM.AddTransition(new HandTransition(m_FSwapping, __Xd_, m_Empty, new HandActionDestroyed, new HandGuardHasDestroyedItemInHands(GetManOwner())));
  222. m_FSwapping.AddTransition(new HandTransition( m_FSwapping.m_Start, _abt_, m_Equipped));
  223. m_FSwapping.AddTransition(new HandTransition( m_FSwapping.m_Hide, _abt_, m_Empty));
  224. m_FSwapping.AddTransition(new HandTransition( m_FSwapping.m_Show, _abt_, m_Equipped));
  225. super.Init(); // initialize ordinary human fsm (no anims)
  226. }
  227. /**@fn CancelHandEvent
  228. * @brief cancels any handevents that will be executed this frame
  229. * @NOTE: this is used in situations where the player performs an action that renders the event invalid exactly on the frame it will be executed
  230. **/
  231. void CancelHandEvent ()
  232. {
  233. m_DeferredPostedHandEvent = null;
  234. //m_postedHandEvent = null;
  235. }
  236. void CancelWeaponEvent ()
  237. {
  238. m_DeferredWeaponEvent = null;
  239. m_DeferredWeaponTimer.Stop();
  240. }
  241. void AbortWeaponEvent ()
  242. {
  243. HumanCommandWeapons hcw = GetDayZPlayerOwner().GetCommandModifier_Weapons();
  244. Weapon_Base weapon;
  245. Class.CastTo(weapon, GetEntityInHands());
  246. if (hcw && weapon && weapon.CanProcessWeaponEvents() && !weapon.IsIdle())
  247. {
  248. if (LogManager.IsWeaponLogEnable())
  249. {
  250. wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(weapon) + " Weapon event: ABORT! notifying running state=" + weapon.GetCurrentState());
  251. }
  252. weapon.ProcessWeaponAbortEvent(new WeaponEventHumanCommandActionAborted(GetDayZPlayerOwner()));
  253. }
  254. }
  255. /**@fn PostWeaponEvent
  256. * @brief deferred weapon's fsm handling of events
  257. * @NOTE: "post" stores the event for later use when ::CommandHandler is being run
  258. **/
  259. void PostWeaponEvent (WeaponEventBase e)
  260. {
  261. if (m_DeferredWeaponEvent == NULL)
  262. {
  263. m_DeferredWeaponEvent = e;
  264. if (LogManager.IsWeaponLogEnable())
  265. {
  266. wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(GetInventoryOwner()) + " Posted event m_DeferredWeaponEvent=" + m_DeferredWeaponEvent.DumpToString());
  267. }
  268. }
  269. else
  270. {
  271. Error("[wpnfsm] " + Object.GetDebugName(GetInventoryOwner()) + " warning - pending event already posted, curr_event=" + m_DeferredWeaponEvent.DumpToString() + " new_event=" + e.DumpToString());
  272. }
  273. }
  274. void DeferredWeaponFailed()
  275. {
  276. Weapon_Base weapon;
  277. Class.CastTo(weapon, GetEntityInHands());
  278. string secondPart = " - ENTITY IN HANDS IS NOT A WEAPON: " + Object.GetDebugName(GetEntityInHands());
  279. string firstPart = "[wpnfsm] " + Object.GetDebugName(GetInventoryOwner()) + " failed to perform weaponevent " + m_DeferredWeaponEvent.DumpToString();
  280. if (weapon)
  281. {
  282. secondPart = " on " + Object.GetDebugName(GetEntityInHands()) + " which is in state " + weapon.GetCurrentState();
  283. secondPart += " with physical state: J: " + weapon.IsJammed() + " | ";
  284. for (int i = 0; i < weapon.GetMuzzleCount(); ++i)
  285. {
  286. secondPart += "Chamber_" + i + ": B(" + weapon.IsChamberFull(i) + ") F(" + weapon.IsChamberFiredOut(i) + ") E(" + weapon.IsChamberEmpty(i) + ") | ";
  287. secondPart += "Magazine_" + i + ": " + weapon.GetMagazine(i);
  288. if (i < weapon.GetMuzzleCount() - 1)
  289. secondPart += " | ";
  290. }
  291. }
  292. Error(firstPart + secondPart);
  293. CancelWeaponEvent();
  294. }
  295. void HandleWeaponEvents (float dt, out bool exitIronSights)
  296. {
  297. HumanCommandWeapons hcw = GetDayZPlayerOwner().GetCommandModifier_Weapons();
  298. Weapon_Base weapon;
  299. Class.CastTo(weapon, GetEntityInHands());
  300. if (weapon)
  301. {
  302. weapon.UpdateCoolDown(dt);
  303. if (hcw && weapon.CanProcessWeaponEvents())
  304. {
  305. weapon.GetCurrentState().OnUpdate(dt);
  306. if (LogManager.IsWeaponLogEnable())
  307. {
  308. wpnDebugSpamALot("[wpnfsm] " + Object.GetDebugName(weapon) + " HCW: playing A=" + typename.EnumToString(WeaponActions, hcw.GetRunningAction()) + " AT=" + WeaponActionTypeToString(hcw.GetRunningAction(), hcw.GetRunningActionType()) + " fini=" + hcw.IsActionFinished());
  309. }
  310. if (!weapon.IsIdle())
  311. {
  312. while (true)
  313. {
  314. int weaponEventId = hcw.IsEvent();
  315. if (weaponEventId == -1)
  316. {
  317. break;
  318. }
  319. if (weaponEventId == WeaponEvents.CHANGE_HIDE)
  320. {
  321. break;
  322. }
  323. WeaponEventBase anim_event = WeaponAnimEventFactory(weaponEventId, GetDayZPlayerOwner(), NULL);
  324. if (LogManager.IsWeaponLogEnable())
  325. {
  326. wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(weapon) + " HandleWeapons: event arrived " + typename.EnumToString(WeaponEvents, weaponEventId) + "(" + weaponEventId + ") fsm_ev=" + anim_event.ToString());
  327. }
  328. if (anim_event != NULL)
  329. {
  330. weapon.ProcessWeaponEvent(anim_event);
  331. }
  332. }
  333. if (hcw.IsActionFinished())
  334. {
  335. if (weapon.IsWaitingForActionFinish())
  336. {
  337. if (LogManager.IsWeaponLogEnable())
  338. {
  339. wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(weapon) + " Weapon event: finished! notifying waiting state=" + weapon.GetCurrentState());
  340. }
  341. weapon.ProcessWeaponEvent(new WeaponEventHumanCommandActionFinished(GetDayZPlayerOwner()));
  342. }
  343. else
  344. {
  345. if (LogManager.IsWeaponLogEnable())
  346. {
  347. wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(weapon) + " Weapon event: ABORT! notifying running state=" + weapon.GetCurrentState());
  348. }
  349. weapon.ProcessWeaponAbortEvent(new WeaponEventHumanCommandActionAborted(GetDayZPlayerOwner()));
  350. }
  351. }
  352. }
  353. if (m_DeferredWeaponEvent)
  354. {
  355. if (LogManager.IsWeaponLogEnable())
  356. {
  357. wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(weapon) + " Weapon event: deferred " + m_DeferredWeaponEvent.DumpToString());
  358. }
  359. if (weapon.ProcessWeaponEvent(m_DeferredWeaponEvent))
  360. {
  361. exitIronSights = true;
  362. if (LogManager.IsWeaponLogEnable())
  363. {
  364. fsmDebugSpam("[wpnfsm] " + Object.GetDebugName(weapon) + " Weapon event: resetting deferred event" + m_DeferredWeaponEvent.DumpToString());
  365. }
  366. m_DeferredWeaponEvent = NULL;
  367. m_DeferredWeaponTimer.Stop();
  368. }
  369. else if (!m_DeferredWeaponTimer.IsRunning())
  370. {
  371. m_DeferredWeaponTimer.Run(3, this, "DeferredWeaponFailed");
  372. }
  373. }
  374. }
  375. }
  376. }
  377. void HandleInventory(float dt)
  378. {
  379. HumanCommandWeapons hcw = GetDayZPlayerOwner().GetCommandModifier_Weapons();
  380. EntityAI ih = GetEntityInHands();
  381. Weapon_Base weapon;
  382. Class.CastTo(weapon, ih);
  383. if (hcw)
  384. {
  385. m_FSM.GetCurrentState().OnUpdate(dt);
  386. #ifdef ENABLE_LOGGING
  387. if (LogManager.IsInventoryHFSMLogEnable())
  388. {
  389. hndDebugSpamALot("[hndfsm] HCW: playing A=" + typename.EnumToString(WeaponActions, hcw.GetRunningAction()) + " AT=" + WeaponActionTypeToString(hcw.GetRunningAction(), hcw.GetRunningActionType()) + " fini=" + hcw.IsActionFinished());
  390. }
  391. #endif
  392. if ( !m_FSM.GetCurrentState().IsIdle() || !m_FSM.IsRunning())
  393. {
  394. while (true)
  395. {
  396. int weaponEventId = hcw.IsEvent();
  397. if (weaponEventId == -1)
  398. {
  399. break;
  400. }
  401. HandEventBase anim_event = HandAnimEventFactory(weaponEventId, GetManOwner(), NULL);
  402. #ifdef ENABLE_LOGGING
  403. if (LogManager.IsInventoryHFSMLogEnable())
  404. {
  405. hndDebugPrint("[hndfsm] HandleInventory: event arrived " + typename.EnumToString(WeaponEvents, weaponEventId) + "(" + weaponEventId + ") fsm_ev=" + anim_event.ToString());
  406. }
  407. #endif
  408. if (anim_event != NULL)
  409. {
  410. SyncHandEventToRemote(anim_event);
  411. ProcessHandEvent(anim_event);
  412. }
  413. }
  414. if (hcw.IsActionFinished())
  415. {
  416. if (m_FSM.GetCurrentState().IsWaitingForActionFinish())
  417. {
  418. #ifdef ENABLE_LOGGING
  419. if (LogManager.IsInventoryHFSMLogEnable())
  420. {
  421. hndDebugPrint("[hndfsm] Hand-Weapon event: finished! notifying waiting state=" + m_FSM.GetCurrentState());
  422. }
  423. #endif
  424. HandEventBase fin_event = new HandEventHumanCommandActionFinished(GetManOwner());
  425. SyncHandEventToRemote(fin_event);
  426. ProcessHandEvent(fin_event);
  427. }
  428. else
  429. {
  430. #ifdef ENABLE_LOGGING
  431. if (LogManager.IsInventoryHFSMLogEnable())
  432. {
  433. hndDebugPrint("[hndfsm] Hand-Weapon event: ABORT! notifying running state=" + m_FSM.GetCurrentState());
  434. }
  435. #endif
  436. HandEventBase abt_event = new HandEventHumanCommandActionAborted(GetManOwner());
  437. SyncHandEventToRemote(abt_event);
  438. ProcessHandAbortEvent(abt_event);
  439. //m_FSM.ProcessHandAbortEvent(new WeaponEventHumanCommandActionAborted(GetManOwner()));
  440. }
  441. }
  442. }
  443. }
  444. }
  445. ///@{ juncture
  446. /**@fn OnInventoryJunctureFromServer
  447. * @brief reaction to engine callback
  448. * originates in:
  449. * engine - DayZPlayer::OnSyncJuncture
  450. * script - PlayerBase.OnSyncJuncture
  451. **/
  452. override bool OnInventoryJunctureFromServer (ParamsReadContext ctx)
  453. {
  454. int tmp = -1;
  455. ctx.Read(tmp);
  456. #ifdef ENABLE_LOGGING
  457. if (LogManager.IsSyncLogEnable())
  458. {
  459. syncDebugPrint("[syncinv] " + Object.GetDebugName(GetDayZPlayerOwner()) + " store Juncture packet STS = " + GetDayZPlayerOwner().GetSimulationTimeStamp());
  460. }
  461. #endif
  462. StoreJunctureData(ctx);
  463. return true;
  464. }
  465. ///@{ juncture
  466. /**@fn OnInventoryJunctureFromServer
  467. * @brief reaction to engine callback
  468. * originates in:
  469. * engine - DayZPlayer::OnSyncJuncture
  470. * script - PlayerBase.OnSyncJuncture
  471. **/
  472. override bool OnInventoryJunctureRepairFromServer (ParamsReadContext ctx)
  473. {
  474. /* InventoryLocation il = new InventoryLocation;
  475. if (!il.ReadFromContext(ctx) )
  476. return false;
  477. InventoryLocation il_current = new InventoryLocation;
  478. EntityAI item = il.GetItem();
  479. item.GetInventory().GetCurrentInventoryLocation(il_current);
  480. if( !il_current.CompareLocationOnly(il))
  481. {
  482. LocationMoveEntity(il_current,il);
  483. }*/
  484. return true;
  485. }
  486. ///@{ juncture
  487. /**@fn OnInventoryJunctureFailureFromServer
  488. * @brief reaction to engine callback
  489. * originates in:
  490. * engine - DayZPlayer::OnSyncJuncture
  491. * script - PlayerBase.OnSyncJuncture
  492. **/
  493. override void OnInventoryJunctureFailureFromServer(ParamsReadContext ctx)
  494. {
  495. /**
  496. * Function and setup is still messy due to the switch statement and relation with reading.
  497. *
  498. * It could be cleaner if we used classes to handle each inventory command type, but that comes at a performance cost and will also probably require making a fair amount of changes elsewhere.
  499. *
  500. * The downsides with this system right now:
  501. * 1. It makes it hard to track what is written/read from the serializer
  502. * 2. It makes this file very very large
  503. *
  504. * The new changes at least remove the massive switch block and allow for all inventory commands to respond back to the client if something goes wrong
  505. *
  506. */
  507. if (GetGame().IsDedicatedServer())
  508. {
  509. return;
  510. }
  511. int udtIdentifier = -1;
  512. if (!ctx.Read(udtIdentifier) || udtIdentifier != INPUT_UDT_INVENTORY)
  513. {
  514. return;
  515. }
  516. InventoryLocation src = new InventoryLocation;
  517. InventoryLocation dst = new InventoryLocation;
  518. InventoryLocation temp = new InventoryLocation;
  519. InventoryCommandType type = -1;
  520. if (!ctx.Read(type))
  521. {
  522. return;
  523. }
  524. switch (type)
  525. {
  526. case InventoryCommandType.SYNC_MOVE:
  527. {
  528. src.ReadFromContext(ctx);
  529. dst.ReadFromContext(ctx);
  530. ClearInventoryReservationEx(dst.GetItem(), dst);
  531. break;
  532. }
  533. case InventoryCommandType.HAND_EVENT:
  534. {
  535. HandEventBase e = HandEventBase.CreateHandEventFromContext(ctx);
  536. src = e.GetSrc();
  537. dst = e.GetDst();
  538. e.ClearInventoryReservation();
  539. break;
  540. }
  541. case InventoryCommandType.SWAP:
  542. {
  543. src.ReadFromContext(ctx);
  544. temp.ReadFromContext(ctx);
  545. dst.ReadFromContext(ctx);
  546. temp.ReadFromContext(ctx);
  547. ClearInventoryReservationEx(dst.GetItem(), dst);
  548. ClearInventoryReservationEx(temp.GetItem(), temp);
  549. break;
  550. }
  551. case InventoryCommandType.FORCESWAP:
  552. {
  553. break;
  554. }
  555. case InventoryCommandType.DESTROY:
  556. {
  557. src.ReadFromContext(ctx);
  558. break;
  559. }
  560. }
  561. InventoryValidationReason reason;
  562. if (!ctx.Read(reason))
  563. {
  564. reason = InventoryValidationReason.UNKNOWN;
  565. }
  566. OnInventoryFailure(type, reason, src, dst);
  567. }
  568. override void OnInventoryFailure(InventoryCommandType type, InventoryValidationReason reason, InventoryLocation src, InventoryLocation dst)
  569. {
  570. if (reason == InventoryValidationReason.DROP_PREVENTED)
  571. {
  572. //! TODO(kumarjac): Notify player here
  573. return;
  574. }
  575. }
  576. /**@fn OnHandleStoredJunctureData
  577. * @brief reaction to engine callback
  578. * originates in engine - DayZPlayerInventory::HandleStoredJunctureData
  579. **/
  580. protected void OnHandleStoredJunctureData(ParamsReadContext ctx)
  581. {
  582. int tmp = -1;
  583. ctx.Read(tmp);
  584. #ifdef ENABLE_LOGGING
  585. if (LogManager.IsSyncLogEnable())
  586. {
  587. syncDebugPrint("[syncinv] " + Object.GetDebugName(GetDayZPlayerOwner()) + " handle JunctureData packet STS = " + GetDayZPlayerOwner().GetSimulationTimeStamp());
  588. }
  589. #endif
  590. //! Juncture is only ever Server Req->Client Ack and Perform->Server Perform, never remote
  591. ProcessInputData(ctx, true, false);
  592. }
  593. /**@fn StoreJunctureData
  594. * @brief stores received input user data for later handling
  595. /aaa
  596. **/
  597. proto native void StoreJunctureData(ParamsReadContext ctx);
  598. ///@} juncture
  599. ///@{ input user data
  600. /**@fn OnInputUserDataProcess
  601. * @brief reaction to engine callback
  602. * originates in:
  603. * engine - DayZPlayer::OnInputUserDataReceived
  604. * script - DayZPlayerImplement.OnInputUserDataReceived
  605. **/
  606. override bool OnInputUserDataProcess(ParamsReadContext ctx)
  607. {
  608. #ifdef ENABLE_LOGGING
  609. if (LogManager.IsSyncLogEnable())
  610. {
  611. syncDebugPrint("[syncinv] " + Object.GetDebugName(GetDayZPlayerOwner()) + " store InputUserData packet STS = " + GetDayZPlayerOwner().GetSimulationTimeStamp());
  612. }
  613. #endif
  614. StoreInputUserData(ctx);
  615. return true;
  616. }
  617. /**@fn OnHandleStoredInputUserData
  618. * @brief reaction to engine callback
  619. * originates in engine - DayZPlayerInventory::HandleStoredInputUserData
  620. **/
  621. protected void OnHandleStoredInputUserData(ParamsReadContext ctx)
  622. {
  623. int tmp = -1;
  624. ctx.Read(tmp);
  625. #ifdef ENABLE_LOGGING
  626. if (LogManager.IsSyncLogEnable())
  627. {
  628. syncDebugPrint("[syncinv] " + Object.GetDebugName(GetDayZPlayerOwner()) + " handle InputUserData packet STS = " + GetDayZPlayerOwner().GetSimulationTimeStamp());
  629. }
  630. #endif
  631. ProcessInputData(ctx, false, false);
  632. }
  633. /**@fn StoreInputUserData
  634. * @brief stores received input user data for later handling
  635. **/
  636. proto native void StoreInputUserData(ParamsReadContext ctx);
  637. ///@} input user data
  638. void OnInputUserDataForRemote(ParamsReadContext ctx)
  639. {
  640. #ifdef ENABLE_LOGGING
  641. if (LogManager.IsSyncLogEnable())
  642. {
  643. syncDebugPrint("[syncinv] " + Object.GetDebugName(GetDayZPlayerOwner()) + " remote handling InputUserData packet from server");
  644. }
  645. #endif
  646. ProcessInputData(ctx, false, true);
  647. }
  648. override void OnServerInventoryCommand(ParamsReadContext ctx)
  649. {
  650. #ifdef ENABLE_LOGGING
  651. if (LogManager.IsSyncLogEnable())
  652. {
  653. syncDebugPrint("[syncinv] " + Object.GetDebugName(GetDayZPlayerOwner()) + " DZPInventory command from server");
  654. }
  655. #endif
  656. ProcessInputData(ctx, true, true);
  657. }
  658. bool ValidateSyncMove(inout Serializer ctx, InventoryValidation validation)
  659. {
  660. InventoryCommandType type = InventoryCommandType.SYNC_MOVE;
  661. InventoryLocation src = new InventoryLocation;
  662. InventoryLocation dst = new InventoryLocation;
  663. bool success = true;
  664. src.ReadFromContext(ctx);
  665. dst.ReadFromContext(ctx);
  666. #ifdef ENABLE_LOGGING
  667. if (LogManager.IsInventoryMoveLogEnable())
  668. {
  669. Debug.InventoryMoveLog("STS = " + GetDayZPlayerOwner().GetSimulationTimeStamp() + "src=" + InventoryLocation.DumpToStringNullSafe(src) + " dst=" + InventoryLocation.DumpToStringNullSafe(dst), "SYNC_MOVE" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  670. }
  671. #endif
  672. if (validation.m_IsRemote && (!src.GetItem() || !dst.GetItem()))
  673. {
  674. //! kumarjac: This indicates a failure in replication relationships as player full inventory should be synchronized always if player exists on the remote
  675. #ifdef ENABLE_LOGGING
  676. if (LogManager.IsInventoryMoveLogEnable())
  677. {
  678. Debug.InventoryMoveLog("Failed - item not in bubble", "SYNC_MOVE" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  679. }
  680. if (LogManager.IsSyncLogEnable())
  681. {
  682. syncDebugPrint("[syncinv] HandleInputData remote input (cmd=SYNC_MOVE) dropped, item not in bubble! src=" + InventoryLocation.DumpToStringNullSafe(src) + " dst=" + InventoryLocation.DumpToStringNullSafe(dst));
  683. }
  684. #endif
  685. return true;
  686. }
  687. EnableMovableOverride(src.GetItem());
  688. //! Do not check for action validity on remotes or when performing through juncture.
  689. //! Juncture locks guarentee the item is safe to interact with and the server has validated the command at this point.
  690. //! Checking at this point is both wasteful and can result in a failure which leads to desync
  691. if (success && !validation.m_IsRemote && !validation.m_IsJuncture && !PlayerCheckRequestSrc(src, GameInventory.c_MaxItemDistanceRadius))
  692. {
  693. //! kumarjac: This indicates a failure in replication relationships as player full inventory should be synchronized always if player exists on the remote
  694. #ifdef ENABLE_LOGGING
  695. if (LogManager.IsInventoryMoveLogEnable())
  696. {
  697. Debug.InventoryMoveLog("Failed - CheckRequestSrc", "SYNC_MOVE" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  698. }
  699. if (LogManager.IsSyncLogEnable())
  700. {
  701. syncDebugPrint("[cheat] HandleInputData man=" + Object.GetDebugName(GetManOwner()) + " failed src check with cmd=" + typename.EnumToString(InventoryCommandType, type) + " src=" + InventoryLocation.DumpToStringNullSafe(src));
  702. }
  703. #endif
  704. RemoveMovableOverride(src.GetItem());
  705. if (GetDayZPlayerOwner().GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER)
  706. {
  707. success = false;
  708. }
  709. else
  710. {
  711. return true;
  712. }
  713. }
  714. //! Do not check for action validity on remotes or when performing through juncture.
  715. //! Juncture locks guarentee the item is safe to interact with and the server has validated the command at this point.
  716. //! Checking at this point is both wasteful and can result in a failure which leads to desync
  717. if (success && !validation.m_IsRemote && !validation.m_IsJuncture && !PlayerCheckRequestDst(src, dst, GameInventory.c_MaxItemDistanceRadius))
  718. {
  719. #ifdef ENABLE_LOGGING
  720. if (LogManager.IsInventoryMoveLogEnable())
  721. {
  722. Debug.InventoryMoveLog("Failed - CheckMoveToDstRequest", "SYNC_MOVE" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  723. }
  724. if (LogManager.IsSyncLogEnable())
  725. {
  726. syncDebugPrint("[cheat] HandleInputData man=" + Object.GetDebugName(GetManOwner()) + " is cheating with cmd=" + typename.EnumToString(InventoryCommandType, type) + " src=" + InventoryLocation.DumpToStringNullSafe(src) + " dst=" + InventoryLocation.DumpToStringNullSafe(dst));
  727. }
  728. #endif
  729. RemoveMovableOverride(src.GetItem());
  730. if (GetDayZPlayerOwner().GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER)
  731. {
  732. success = false;
  733. }
  734. else
  735. {
  736. return true;
  737. }
  738. }
  739. RemoveMovableOverride(src.GetItem());
  740. #ifdef ENABLE_LOGGING
  741. if (LogManager.IsSyncLogEnable())
  742. {
  743. syncDebugPrint("[syncinv] " + Object.GetDebugName(GetDayZPlayerOwner()) + " STS = " + GetDayZPlayerOwner().GetSimulationTimeStamp() + " HandleInputData t=" + GetGame().GetTime() + "ms received cmd=" + typename.EnumToString(InventoryCommandType, type) + " src=" + InventoryLocation.DumpToStringNullSafe(src) + " dst=" + InventoryLocation.DumpToStringNullSafe(dst));
  744. }
  745. #endif
  746. //! Check if this this is being executed on the server and not by a juncture or AI so we can lock the item and ensure replication relationships are setup
  747. if (!validation.m_IsJuncture && GetDayZPlayerOwner().GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER)
  748. {
  749. JunctureRequestResult result_mv = TryAcquireInventoryJunctureFromServer(GetDayZPlayerOwner(), src, dst);
  750. if (result_mv == JunctureRequestResult.JUNCTURE_NOT_REQUIRED)
  751. {
  752. #ifdef ENABLE_LOGGING
  753. if (LogManager.IsInventoryMoveLogEnable())
  754. {
  755. Debug.InventoryMoveLog("Juncture not required", "SYNC_MOVE" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  756. }
  757. #endif
  758. if (success)
  759. {
  760. //! TODO(kumarjac): We should continue with the execution and not have this special block but making a change here now will require testing
  761. LocationSyncMoveEntity(src, dst);
  762. validation.m_Result = InventoryValidationResult.SUCCESS;
  763. }
  764. return true;
  765. }
  766. else if (success && result_mv == JunctureRequestResult.JUNCTURE_ACQUIRED)
  767. {
  768. #ifdef ENABLE_LOGGING
  769. if (LogManager.IsInventoryMoveLogEnable())
  770. {
  771. Debug.InventoryMoveLog("Juncture sended", "SYNC_MOVE" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  772. }
  773. #endif
  774. if (!GameInventory.LocationCanMoveEntity(src, dst))
  775. {
  776. #ifdef ENABLE_LOGGING
  777. #ifdef DEVELOPER
  778. DumpInventoryDebug();
  779. #endif
  780. if (LogManager.IsInventoryMoveLogEnable())
  781. {
  782. Debug.InventoryMoveLog("Failed - LocationCanMoveEntity - Juncture denied", "SYNC_MOVE" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  783. }
  784. #endif
  785. validation.m_Result = InventoryValidationResult.FAILED;
  786. return true;
  787. }
  788. validation.m_Result = InventoryValidationResult.JUNCTURE;
  789. EnableMovableOverride(src.GetItem());
  790. return true;
  791. }
  792. else
  793. {
  794. #ifdef ENABLE_LOGGING
  795. if ( LogManager.IsInventoryMoveLogEnable() )
  796. {
  797. Debug.InventoryMoveLog("Juncture denied", "SYNC_MOVE" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  798. }
  799. #endif
  800. validation.m_Result = InventoryValidationResult.FAILED;
  801. validation.m_Reason = InventoryValidationReason.JUNCTURE_DENIED;
  802. return true;
  803. }
  804. }
  805. if (GetDayZPlayerOwner().GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_CLIENT)
  806. {
  807. ClearInventoryReservationEx(dst.GetItem(), dst);
  808. }
  809. //! Is called twice unfortunately...
  810. if (GetDayZPlayerOwner().GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER)
  811. {
  812. CheckForRope(src, dst);
  813. }
  814. //! Do not check for action validity on remotes or when performing through juncture.
  815. //! Juncture locks guarentee the item is safe to interact with and the server has validated the command at this point.
  816. //! Checking at this point is both wasteful and can result in a failure which leads to desync
  817. if (!validation.m_IsRemote && !validation.m_IsJuncture && !GameInventory.LocationCanMoveEntitySyncCheck(src, dst))
  818. {
  819. #ifdef ENABLE_LOGGING
  820. #ifdef DEVELOPER
  821. DumpInventoryDebug();
  822. #endif
  823. if (LogManager.IsInventoryMoveLogEnable())
  824. {
  825. Debug.InventoryMoveLog("Failed - LocationCanMoveEntity", "SYNC_MOVE" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  826. }
  827. #endif
  828. Error("[desync] HandleInputData man=" + Object.GetDebugName(GetManOwner()) + " CANNOT move cmd=" + typename.EnumToString(InventoryCommandType, type) + " src=" + InventoryLocation.DumpToStringNullSafe(src) + " dst=" + InventoryLocation.DumpToStringNullSafe(dst));
  829. return true;
  830. }
  831. //TODO: hotfix solution
  832. if (!validation.m_IsRemote && validation.m_IsJuncture && !MoveCheckExclusionMaskLocal(src,dst))
  833. {
  834. #ifdef ENABLE_LOGGING
  835. if (LogManager.IsInventoryMoveLogEnable())
  836. {
  837. Debug.InventoryMoveLog("Failed - MoveCheckExclusionMaskLocal - condition failed locally", "SYNC_MOVE" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  838. }
  839. #endif
  840. return false;
  841. }
  842. #ifdef ENABLE_LOGGING
  843. if (LogManager.IsInventoryMoveLogEnable())
  844. {
  845. Debug.InventoryMoveLog("Success - LocationSyncMoveEntity", "SYNC_MOVE" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  846. }
  847. #endif
  848. LocationSyncMoveEntity(src, dst);
  849. validation.m_Result = InventoryValidationResult.SUCCESS;
  850. return true;
  851. }
  852. bool ValidateHandEvent(inout Serializer ctx, InventoryValidation validation)
  853. {
  854. InventoryCommandType type = InventoryCommandType.HAND_EVENT;
  855. bool success = true;
  856. HandEventBase e = HandEventBase.CreateHandEventFromContext(ctx);
  857. e.ClearInventoryReservation();
  858. //! Pass partial information to guards so guards can do minimal checks if needed
  859. //! The guards can't prevent event so it would be incorrect to pass full InventoryValidation struct.
  860. //! We have to make sure guards don't inadvertantly produce different results in the FSM as that will create desync (two players attempting to put a rag into the same fireplace slot at the same time)
  861. e.m_IsRemote = validation.m_IsRemote;
  862. e.m_IsJuncture = validation.m_IsJuncture;
  863. EntityAI itemSrc = e.GetSrcEntity();
  864. EntityAI itemDst = e.GetSecondSrcEntity();
  865. #ifdef ENABLE_LOGGING
  866. if (LogManager.IsInventoryMoveLogEnable())
  867. {
  868. Debug.InventoryMoveLog("STS = " + e.m_Player.GetSimulationTimeStamp() + " event= " + e.DumpToString(), "HAND_EVENT" , "n/a", "ProcessInputData", e.m_Player.ToString() );
  869. }
  870. #endif
  871. if (validation.m_IsRemote && !e.GetSrcEntity())
  872. {
  873. //! kumarjac: This indicates a failure in replication relationships as player full inventory should be synchronized always if player exists on the remote
  874. #ifdef ENABLE_LOGGING
  875. if (LogManager.IsInventoryMoveLogEnable())
  876. {
  877. Debug.InventoryMoveLog("Failed - CheckRequestSrc", "HAND_EVENT" , "n/a", "ProcessInputData", e.m_Player.ToString() );
  878. }
  879. #endif
  880. Error("[syncinv] HandleInputData remote input (cmd=HAND_EVENT, event=" + e.DumpToString() + ") dropped, item not in bubble");
  881. return true;
  882. }
  883. //! TODO(kumarjac): Is this one correct to be 'RemoveMovableOverride' or are the other Validate methdos wrong with 'EnableMovableOverride'?
  884. if (itemSrc)
  885. RemoveMovableOverride(itemSrc);
  886. if (itemDst)
  887. RemoveMovableOverride(itemDst);
  888. //! Do not check for action validity on remotes or when performing through juncture.
  889. //! Juncture locks guarentee the item is safe to interact with and the server has validated the command at this point.
  890. //! Checking at this point is both wasteful and can result in a failure which leads to desync
  891. if (success && !validation.m_IsRemote && !validation.m_IsJuncture && !e.CheckRequestSrc())
  892. {
  893. #ifdef ENABLE_LOGGING
  894. if (LogManager.IsInventoryMoveLogEnable())
  895. {
  896. Debug.InventoryMoveLog("Failed - CheckRequestSrc", "HAND_EVENT" , "n/a", "ProcessInputData", e.m_Player.ToString() );
  897. }
  898. #endif
  899. if (!validation.m_IsRemote)
  900. {
  901. ctx = new ScriptInputUserData;
  902. InventoryInputUserData.SerializeHandEvent(ctx, e);
  903. }
  904. RemoveMovableOverride(itemSrc);
  905. RemoveMovableOverride(itemDst);
  906. if (GetDayZPlayerOwner().GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER)
  907. {
  908. success = false;
  909. }
  910. else
  911. {
  912. return true;
  913. }
  914. }
  915. if (success && !e.CheckRequestEx(validation))
  916. {
  917. #ifdef ENABLE_LOGGING
  918. if (LogManager.IsInventoryMoveLogEnable())
  919. {
  920. Debug.InventoryMoveLog("Failed - CheckRequest", "HAND_EVENT" , "n/a", "ProcessInputData", e.m_Player.ToString() );
  921. }
  922. #endif
  923. //! 'HandEventBase.CheckRequestEx' updates failure reason
  924. ctx = new ScriptInputUserData;
  925. InventoryInputUserData.SerializeHandEvent(ctx, e);
  926. #ifdef ENABLE_LOGGING
  927. if (LogManager.IsSyncLogEnable())
  928. {
  929. syncDebugPrint("[cheat] HandleInputData man=" + Object.GetDebugName(GetManOwner()) + " STS = " + GetDayZPlayerOwner().GetSimulationTimeStamp() + " is cheating with cmd=" + typename.EnumToString(InventoryCommandType, type) + " event=" + e.DumpToString());
  930. }
  931. #endif
  932. RemoveMovableOverride(itemSrc);
  933. RemoveMovableOverride(itemDst);
  934. if (GetDayZPlayerOwner().GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER)
  935. {
  936. success = false;
  937. }
  938. else
  939. {
  940. return true;
  941. }
  942. }
  943. //! if it already happened on server, remote just needs to comply
  944. //! TODO(kumarjac): Move m_IsRemote check to inside of HandEventBase.CanPerformEventEx
  945. if (success && !validation.m_IsRemote && !e.CanPerformEventEx(validation))
  946. {
  947. #ifdef ENABLE_LOGGING
  948. if (LogManager.IsInventoryMoveLogEnable())
  949. {
  950. Debug.InventoryMoveLog("Failed - CanPerformEvent", "HAND_EVENT" , "n/a", "ProcessInputData", e.m_Player.ToString() );
  951. }
  952. #endif
  953. //! 'HandEventBase.CanPerformEventEx' updates failure reason
  954. ctx = new ScriptInputUserData;
  955. InventoryInputUserData.SerializeHandEvent(ctx, e);
  956. #ifdef ENABLE_LOGGING
  957. if (LogManager.IsSyncLogEnable())
  958. {
  959. syncDebugPrint("[desync] HandleInputData man=" + Object.GetDebugName(GetManOwner()) + " CANNOT do cmd=HAND_EVENT e=" + e.DumpToString());
  960. }
  961. #endif
  962. RemoveMovableOverride(itemSrc);
  963. RemoveMovableOverride(itemDst);
  964. if (GetDayZPlayerOwner().GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER)
  965. {
  966. success = false;
  967. }
  968. else
  969. {
  970. return true;
  971. }
  972. }
  973. RemoveMovableOverride(itemSrc);
  974. RemoveMovableOverride(itemDst);
  975. //! Check if this this is being executed on the server and not by a juncture or AI
  976. if (!validation.m_IsJuncture && GetDayZPlayerOwner().GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER)
  977. {
  978. JunctureRequestResult result_ev = e.AcquireInventoryJunctureFromServer(GetDayZPlayerOwner());
  979. if (result_ev == JunctureRequestResult.JUNCTURE_NOT_REQUIRED)
  980. {
  981. #ifdef ENABLE_LOGGING
  982. if (LogManager.IsInventoryMoveLogEnable())
  983. {
  984. Debug.InventoryMoveLog("Juncture not required", "HAND_EVENT" , "n/a", "ProcessInputData", e.m_Player.ToString() );
  985. }
  986. #endif
  987. //! Continuing on with execution of rest of the function
  988. }
  989. else if (success && result_ev == JunctureRequestResult.JUNCTURE_ACQUIRED)
  990. {
  991. #ifdef ENABLE_LOGGING
  992. if (LogManager.IsInventoryMoveLogEnable())
  993. {
  994. Debug.InventoryMoveLog("Juncture sended", "HAND_EVENT" , "n/a", "ProcessInputData", e.m_Player.ToString() );
  995. }
  996. #endif
  997. ctx = new ScriptInputUserData;
  998. InventoryInputUserData.SerializeHandEvent(ctx, e);
  999. validation.m_Result = InventoryValidationResult.JUNCTURE;
  1000. if (itemSrc)
  1001. EnableMovableOverride(itemSrc);
  1002. if (itemDst)
  1003. EnableMovableOverride(itemDst);
  1004. return true;
  1005. }
  1006. else
  1007. {
  1008. #ifdef ENABLE_LOGGING
  1009. if (LogManager.IsInventoryMoveLogEnable())
  1010. {
  1011. Debug.InventoryMoveLog("Juncture denied", "HAND_EVENT" , "n/a", "ProcessInputData", e.m_Player.ToString() );
  1012. }
  1013. #endif
  1014. validation.m_Reason = InventoryValidationReason.JUNCTURE_DENIED;
  1015. return true;
  1016. }
  1017. }
  1018. //! Is called twice unfortunately... but it works so won't change
  1019. if (success && GetDayZPlayerOwner().GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER)
  1020. {
  1021. CheckForRope(e.GetSrc(), e.GetDst());
  1022. }
  1023. #ifdef ENABLE_LOGGING
  1024. if (LogManager.IsInventoryMoveLogEnable())
  1025. {
  1026. Debug.InventoryMoveLog("Success - ProcessHandEvent", "HAND_EVENT" , "n/a", "ProcessInputData", e.m_Player.ToString() );
  1027. }
  1028. #endif
  1029. if (success)
  1030. {
  1031. validation.m_Result = InventoryValidationResult.SUCCESS;
  1032. if (!e.m_Player.GetHumanInventory().ProcessHandEvent(e))
  1033. {
  1034. //! TODO(kumarjac): We should probably set the result to failure like so
  1035. //result = InventoryValidationResult.FAILURE;
  1036. }
  1037. }
  1038. return true;
  1039. }
  1040. bool ValidateSwap(inout Serializer ctx, InventoryValidation validation)
  1041. {
  1042. InventoryCommandType type = InventoryCommandType.SWAP;
  1043. InventoryLocation src1 = new InventoryLocation;
  1044. InventoryLocation src2 = new InventoryLocation;
  1045. InventoryLocation dst1 = new InventoryLocation;
  1046. InventoryLocation dst2 = new InventoryLocation;
  1047. bool skippedSwap = false;
  1048. bool success = true;
  1049. src1.ReadFromContext(ctx);
  1050. src2.ReadFromContext(ctx);
  1051. dst1.ReadFromContext(ctx);
  1052. dst2.ReadFromContext(ctx);
  1053. ctx.Read(skippedSwap);
  1054. #ifdef ENABLE_LOGGING
  1055. if (LogManager.IsInventoryMoveLogEnable())
  1056. {
  1057. Debug.InventoryMoveLog("STS = " + GetDayZPlayerOwner().GetSimulationTimeStamp() + " src1=" + InventoryLocation.DumpToStringNullSafe(src1) + " dst1=" + InventoryLocation.DumpToStringNullSafe(dst1) + " src2=" + InventoryLocation.DumpToStringNullSafe(src2) + " dst2=" + InventoryLocation.DumpToStringNullSafe(dst2), "SWAP" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  1058. }
  1059. #endif
  1060. if (validation.m_IsRemote && (!src1.GetItem() || !src2.GetItem()))
  1061. {
  1062. if (skippedSwap)
  1063. {
  1064. #ifdef ENABLE_LOGGING
  1065. if (LogManager.IsInventoryMoveLogEnable())
  1066. {
  1067. Debug.InventoryMoveLog("Remote - skipped", "SWAP" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  1068. }
  1069. #endif
  1070. /*
  1071. if (LogManager.IsSyncLogEnable())
  1072. {
  1073. syncDebugPrint("[syncinv] HandleInputData remote input (cmd=SWAP) dropped, swap is skipped");
  1074. }
  1075. */
  1076. }
  1077. else
  1078. {
  1079. //! kumarjac: This indicates a failure in replication relationships as player full inventory should be synchronized always if player exists on the remote
  1080. #ifdef ENABLE_LOGGING
  1081. if (LogManager.IsInventoryMoveLogEnable())
  1082. {
  1083. Debug.InventoryMoveLog("Failed - item1 or item2 not exist", "SWAP" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  1084. }
  1085. #endif
  1086. Error("[syncinv] HandleInputData remote input (cmd=SWAP) dropped, item not in bubble");
  1087. }
  1088. return true;
  1089. }
  1090. EnableMovableOverride(src1.GetItem());
  1091. EnableMovableOverride(src2.GetItem());
  1092. //! Do not check for action validity on remotes or when performing through juncture.
  1093. //! Juncture locks guarentee the item is safe to interact with and the server has validated the command at this point.
  1094. //! Checking at this point is both wasteful and can result in a failure which leads to desync
  1095. if (success && !validation.m_IsRemote && !validation.m_IsJuncture && !PlayerCheckRequestSrc(src1, GameInventory.c_MaxItemDistanceRadius))
  1096. {
  1097. #ifdef ENABLE_LOGGING
  1098. if (LogManager.IsInventoryMoveLogEnable())
  1099. {
  1100. Debug.InventoryMoveLog("Failed - CheckRequestSrc1", "SWAP" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  1101. }
  1102. if (LogManager.IsSyncLogEnable())
  1103. {
  1104. syncDebugPrint("[cheat] HandleInputData man=" + Object.GetDebugName(GetManOwner()) + " failed src1 check with cmd=" + typename.EnumToString(InventoryCommandType, type) + " src1=" + InventoryLocation.DumpToStringNullSafe(src1));
  1105. }
  1106. #endif
  1107. RemoveMovableOverride(src1.GetItem());
  1108. RemoveMovableOverride(src2.GetItem());
  1109. if (GetDayZPlayerOwner().GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER)
  1110. {
  1111. success = false;
  1112. }
  1113. else
  1114. {
  1115. return true;
  1116. }
  1117. }
  1118. //! Do not check for action validity on remotes or when performing through juncture.
  1119. //! Juncture locks guarentee the item is safe to interact with and the server has validated the command at this point.
  1120. //! Checking at this point is both wasteful and can result in a failure which leads to desync
  1121. if (success && !validation.m_IsRemote && !validation.m_IsJuncture && !PlayerCheckRequestSrc(src2, GameInventory.c_MaxItemDistanceRadius))
  1122. {
  1123. #ifdef ENABLE_LOGGING
  1124. if (LogManager.IsInventoryMoveLogEnable())
  1125. {
  1126. Debug.InventoryMoveLog("Failed - CheckRequestSrc2", "SWAP" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  1127. }
  1128. if (LogManager.IsSyncLogEnable())
  1129. {
  1130. syncDebugPrint("[cheat] HandleInputData man=" + Object.GetDebugName(GetManOwner()) + " failed src2 check with cmd=" + typename.EnumToString(InventoryCommandType, type) + " src2=" + InventoryLocation.DumpToStringNullSafe(src2));
  1131. }
  1132. #endif
  1133. RemoveMovableOverride(src1.GetItem());
  1134. RemoveMovableOverride(src2.GetItem());
  1135. if (GetDayZPlayerOwner().GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER)
  1136. {
  1137. success = false;
  1138. }
  1139. else
  1140. {
  1141. return true;
  1142. }
  1143. }
  1144. //! Do not check for action validity on remotes or when performing through juncture.
  1145. //! Juncture locks guarentee the item is safe to interact with and the server has validated the command at this point.
  1146. //! Checking at this point is both wasteful and can result in a failure which leads to desync
  1147. if (success && !validation.m_IsRemote && !validation.m_IsJuncture && !PlayerCheckSwapItemsRequest(src1, src2, dst1, dst2, GameInventory.c_MaxItemDistanceRadius))
  1148. {
  1149. #ifdef ENABLE_LOGGING
  1150. if (LogManager.IsInventoryMoveLogEnable())
  1151. {
  1152. Debug.InventoryMoveLog("Failed - CheckSwapItemsRequest", "SWAP" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  1153. }
  1154. if (LogManager.IsSyncLogEnable())
  1155. {
  1156. syncDebugPrint("[cheat] HandleInputData man=" + Object.GetDebugName(GetManOwner()) + " is cheating with cmd=" + typename.EnumToString(InventoryCommandType, type) + " src1=" + InventoryLocation.DumpToStringNullSafe(src1) + " src2=" + InventoryLocation.DumpToStringNullSafe(src2) + " dst1=" + InventoryLocation.DumpToStringNullSafe(dst1) + " dst2=" + InventoryLocation.DumpToStringNullSafe(dst2));
  1157. }
  1158. #endif
  1159. RemoveMovableOverride(src1.GetItem());
  1160. RemoveMovableOverride(src2.GetItem());
  1161. if (GetDayZPlayerOwner().GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER)
  1162. {
  1163. success = false;
  1164. }
  1165. else
  1166. {
  1167. return true;
  1168. }
  1169. }
  1170. RemoveMovableOverride(src1.GetItem());
  1171. RemoveMovableOverride(src2.GetItem());
  1172. if (GetDayZPlayerOwner().GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_CLIENT)
  1173. {
  1174. ClearInventoryReservationEx(dst1.GetItem(), dst1);
  1175. ClearInventoryReservationEx(dst2.GetItem(), dst2);
  1176. }
  1177. //! Do not check for action validity on remotes or when performing through juncture.
  1178. //! Juncture locks guarentee the item is safe to interact with and the server has validated the command at this point.
  1179. //! Checking at this point is both wasteful and can result in a failure which leads to desync
  1180. if (success && !validation.m_IsRemote && !validation.m_IsJuncture && !GameInventory.CanForceSwapEntitiesEx(src1.GetItem(), dst1, src2.GetItem(), dst2))
  1181. {
  1182. #ifdef ENABLE_LOGGING
  1183. #ifdef DEVELOPER
  1184. DumpInventoryDebug();
  1185. #endif
  1186. if (LogManager.IsInventoryMoveLogEnable())
  1187. {
  1188. Debug.InventoryMoveLog("Failed - CanForceSwapEntitiesEx", "SWAP" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  1189. }
  1190. #endif
  1191. if (GetDayZPlayerOwner().GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER)
  1192. {
  1193. success = false;
  1194. }
  1195. else
  1196. {
  1197. Error("[desync] HandleInputData man=" + Object.GetDebugName(GetManOwner()) + " CANNOT swap cmd=" + typename.EnumToString(InventoryCommandType, type) + " src1=" + InventoryLocation.DumpToStringNullSafe(src1) + " dst1=" + InventoryLocation.DumpToStringNullSafe(dst1) +" | src2=" + InventoryLocation.DumpToStringNullSafe(src2) + " dst2=" + InventoryLocation.DumpToStringNullSafe(dst2));
  1198. return true;
  1199. }
  1200. }
  1201. if (GetDayZPlayerOwner().GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_CLIENT)
  1202. {
  1203. AddInventoryReservationEx(dst1.GetItem(), dst1, GameInventory.c_InventoryReservationTimeoutShortMS);
  1204. AddInventoryReservationEx(dst2.GetItem(), dst2, GameInventory.c_InventoryReservationTimeoutShortMS);
  1205. }
  1206. if (!(src1.IsValid() && src2.IsValid() && dst1.IsValid() && dst2.IsValid()))
  1207. {
  1208. Error("HandleInputData: cmd=" + typename.EnumToString(InventoryCommandType, type) + " invalid input(s): src1=" + InventoryLocation.DumpToStringNullSafe(src1) + " src2=" + InventoryLocation.DumpToStringNullSafe(src2) + " dst1=" + InventoryLocation.DumpToStringNullSafe(dst1) + " dst2=" + InventoryLocation.DumpToStringNullSafe(dst2));
  1209. return true;
  1210. }
  1211. //! Check if this this is being executed on the server and not by a juncture or AI
  1212. if (!validation.m_IsJuncture && GetDayZPlayerOwner().GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER)
  1213. {
  1214. JunctureRequestResult result_sw = TryAcquireTwoInventoryJuncturesFromServer(GetDayZPlayerOwner(), src1, src2, dst1, dst2);
  1215. if (result_sw == JunctureRequestResult.JUNCTURE_NOT_REQUIRED)
  1216. {
  1217. #ifdef ENABLE_LOGGING
  1218. if (LogManager.IsInventoryMoveLogEnable())
  1219. {
  1220. Debug.InventoryMoveLog("Juncture not required", "SWAP" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  1221. }
  1222. #endif
  1223. //! Continuing on with execution of rest of the function
  1224. }
  1225. else if (success && result_sw == JunctureRequestResult.JUNCTURE_ACQUIRED)
  1226. {
  1227. #ifdef ENABLE_LOGGING
  1228. if (LogManager.IsInventoryMoveLogEnable())
  1229. {
  1230. Debug.InventoryMoveLog("Juncture sended", "SWAP" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  1231. }
  1232. #endif
  1233. validation.m_Result = InventoryValidationResult.JUNCTURE;
  1234. EnableMovableOverride(src1.GetItem());
  1235. EnableMovableOverride(src2.GetItem());
  1236. return true;
  1237. }
  1238. else
  1239. {
  1240. #ifdef ENABLE_LOGGING
  1241. if (LogManager.IsInventoryMoveLogEnable())
  1242. {
  1243. Debug.InventoryMoveLog("Juncture denied", "SWAP" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  1244. }
  1245. #endif
  1246. validation.m_Result = InventoryValidationResult.FAILED;
  1247. validation.m_Reason = InventoryValidationReason.JUNCTURE_DENIED;
  1248. return true;
  1249. }
  1250. }
  1251. if (GetDayZPlayerOwner().GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_CLIENT )
  1252. {
  1253. ClearInventoryReservationEx(dst1.GetItem(), dst1);
  1254. ClearInventoryReservationEx(dst2.GetItem(), dst2);
  1255. }
  1256. else
  1257. {
  1258. GetGame().ClearJunctureEx(GetDayZPlayerOwner(), dst1.GetItem());
  1259. GetGame().ClearJunctureEx(GetDayZPlayerOwner(), dst2.GetItem());
  1260. }
  1261. //TODO: hotfix solution
  1262. if (!validation.m_IsRemote && validation.m_IsJuncture && !SwapCheckExclusionMaskLocal(src1,src2,dst1,dst2))
  1263. {
  1264. #ifdef ENABLE_LOGGING
  1265. if (LogManager.IsInventoryMoveLogEnable())
  1266. {
  1267. Debug.InventoryMoveLog("Failed - !SwapCheckExclusionMaskLocal - condition failed locally", "SYNC_MOVE" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  1268. }
  1269. #endif
  1270. return false;
  1271. }
  1272. #ifdef ENABLE_LOGGING
  1273. if (LogManager.IsInventoryMoveLogEnable())
  1274. {
  1275. Debug.InventoryMoveLog("Success - item swap", "SWAP" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  1276. }
  1277. #endif
  1278. if (success)
  1279. {
  1280. bool isNotSkipped = LocationSwap(src1, src2, dst1, dst2);
  1281. ctx = new ScriptInputUserData();
  1282. InventoryInputUserData.SerializeSwap(ctx, src1, src2, dst1, dst2, !isNotSkipped);
  1283. validation.m_Result = InventoryValidationResult.SUCCESS;
  1284. }
  1285. return true;
  1286. }
  1287. /**
  1288. *
  1289. * @return false on malformed data, true on anything else, including cheats
  1290. */
  1291. bool ProcessInputData(ParamsReadContext ctx, bool isJuncture, bool isRemote)
  1292. {
  1293. if (isJuncture && isRemote)
  1294. {
  1295. //! It should be impossible for juncture to be ran on remote
  1296. return false;
  1297. }
  1298. int type = -1;
  1299. if (!ctx.Read(type))
  1300. {
  1301. return false;
  1302. }
  1303. InventoryValidation validation();
  1304. validation.m_IsJuncture = isJuncture;
  1305. validation.m_IsRemote = isRemote;
  1306. //! Serializer can be updated and re-written to when we may want to only correct the client instead of denying the inventory command
  1307. Serializer serializer = ctx;
  1308. switch (type)
  1309. {
  1310. case InventoryCommandType.USER_RESERVATION_CANCEL:
  1311. if (!ValidateUserReservationCancel(serializer, validation))
  1312. {
  1313. return false;
  1314. }
  1315. break;
  1316. case InventoryCommandType.SYNC_MOVE:
  1317. if (!ValidateSyncMove(serializer, validation))
  1318. {
  1319. return false;
  1320. }
  1321. break;
  1322. case InventoryCommandType.HAND_EVENT:
  1323. if (!ValidateHandEvent(serializer, validation))
  1324. {
  1325. return false;
  1326. }
  1327. break;
  1328. case InventoryCommandType.SWAP:
  1329. if (!ValidateSwap(serializer, validation))
  1330. {
  1331. return false;
  1332. }
  1333. break;
  1334. default:
  1335. break;
  1336. }
  1337. bool canSendJuncture = !isJuncture && GetDayZPlayerOwner().GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER;
  1338. switch (validation.m_Result)
  1339. {
  1340. case InventoryValidationResult.FAILED:
  1341. if (canSendJuncture) //! Only inform client about failure
  1342. {
  1343. //! General purpose serializer change from read to write here if the validation doesn't update it
  1344. if (!serializer.CanWrite())
  1345. {
  1346. ScriptInputUserData writeableSerializer();
  1347. writeableSerializer.CopyFrom(serializer);
  1348. serializer = writeableSerializer;
  1349. }
  1350. serializer.Write(validation.m_Reason);
  1351. GetDayZPlayerOwner().SendSyncJuncture(DayZPlayerSyncJunctures.SJ_INVENTORY_FAILURE, serializer);
  1352. }
  1353. break;
  1354. case InventoryValidationResult.JUNCTURE:
  1355. if (canSendJuncture) //! Only send juncture back to client
  1356. {
  1357. GetDayZPlayerOwner().SendSyncJuncture(DayZPlayerSyncJunctures.SJ_INVENTORY, serializer);
  1358. //StoreInputForRemotes(isJuncture, isRemote, serializer);
  1359. }
  1360. else
  1361. {
  1362. Error("InventoryValidationResult.JUNCTURE returned when not possible to send!");
  1363. }
  1364. break;
  1365. case InventoryValidationResult.SUCCESS:
  1366. StoreInputForRemotes(isJuncture, isRemote, serializer);
  1367. break;
  1368. }
  1369. return true;
  1370. }
  1371. void RemoveMovableOverride(EntityAI item)
  1372. {
  1373. ItemBase itemIB = ItemBase.Cast(item);
  1374. if (itemIB)
  1375. itemIB.SetCanBeMovedOverride(false);
  1376. }
  1377. void EnableMovableOverride(EntityAI item)
  1378. {
  1379. ItemBase itemIB = ItemBase.Cast(item);
  1380. if (itemIB)
  1381. itemIB.SetCanBeMovedOverride(true);
  1382. }
  1383. // Hacky solution for dealing with fencekit rope related issues, could be fixed by introducing some indicator that this item behaves differently or sth..
  1384. void CheckForRope(InventoryLocation src, InventoryLocation dst)
  1385. {
  1386. Rope rope = Rope.Cast(src.GetItem());
  1387. if (rope)
  1388. rope.SetTargetLocation(dst);
  1389. }
  1390. bool IsServerOrLocalPlayer()
  1391. {
  1392. return GetDayZPlayerOwner().GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER || GetDayZPlayerOwner() == GetGame().GetPlayer());
  1393. }
  1394. bool StoreInputForRemotes (bool handling_juncture, bool remote, ParamsReadContext ctx)
  1395. {
  1396. if (!remote && GetDayZPlayerOwner().GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER)
  1397. {
  1398. #ifdef ENABLE_LOGGING
  1399. if (LogManager.IsInventoryMoveLogEnable())
  1400. {
  1401. Debug.InventoryMoveLog("STS = " + GetDayZPlayerOwner().GetSimulationTimeStamp(), "n/a" , "n/a", "StoreInputForRemotes", GetDayZPlayerOwner().ToString() );
  1402. }
  1403. #endif
  1404. GetDayZPlayerOwner().StoreInputForRemotes(ctx); // @NOTE: needs to be called _after_ the operation
  1405. return true;
  1406. }
  1407. return false;
  1408. }
  1409. override bool TakeToDst (InventoryMode mode, notnull InventoryLocation src, notnull InventoryLocation dst)
  1410. {
  1411. if (GetManOwner().IsAlive() == false)
  1412. return super.TakeToDst(mode, src, dst);
  1413. #ifdef ENABLE_LOGGING
  1414. if (LogManager.IsInventoryMoveLogEnable())
  1415. {
  1416. Debug.InventoryMoveLog("STS = " + GetDayZPlayerOwner().GetSimulationTimeStamp() + " src=" + InventoryLocation.DumpToStringNullSafe(src) + " dst=" + InventoryLocation.DumpToStringNullSafe(dst), "n/a" , "n/a", "TakeToDst", GetDayZPlayerOwner().ToString() );
  1417. }
  1418. #endif
  1419. switch (mode)
  1420. {
  1421. case InventoryMode.SERVER:
  1422. if (RedirectToHandEvent(mode, src, dst))
  1423. {
  1424. #ifdef ENABLE_LOGGING
  1425. if (LogManager.IsInventoryMoveLogEnable())
  1426. {
  1427. Debug.InventoryMoveLog("RedirectToHandEvent", "n/a" , "n/a", "TakeToDst", GetDayZPlayerOwner().ToString() );
  1428. }
  1429. #endif
  1430. return true;
  1431. }
  1432. if (GetDayZPlayerOwner().NeedInventoryJunctureFromServer(src.GetItem(), src.GetParent(), dst.GetParent()))
  1433. {
  1434. if (GetGame().AddInventoryJunctureEx(GetDayZPlayerOwner(), src.GetItem(), dst, true, GameInventory.c_InventoryReservationTimeoutMS))
  1435. {
  1436. #ifdef ENABLE_LOGGING
  1437. if (LogManager.IsSyncLogEnable())
  1438. {
  1439. syncDebugPrint("[syncinv] " + Object.GetDebugName(GetDayZPlayerOwner()) + " STS = " + GetDayZPlayerOwner().GetSimulationTimeStamp() + " DZPI::Take2Dst(" + typename.EnumToString(InventoryMode, mode) + ") got juncture");
  1440. }
  1441. #endif
  1442. }
  1443. else
  1444. {
  1445. #ifdef ENABLE_LOGGING
  1446. if (LogManager.IsInventoryMoveLogEnable())
  1447. {
  1448. Debug.InventoryMoveLog("Juncture failed", "n/a" , "n/a", "TakeToDst", GetDayZPlayerOwner().ToString() );
  1449. }
  1450. if (LogManager.IsSyncLogEnable())
  1451. {
  1452. syncDebugPrint("[syncinv] " + Object.GetDebugName(GetDayZPlayerOwner()) + " STS = " + GetDayZPlayerOwner().GetSimulationTimeStamp() + " DZPI::Take2Dst(" + typename.EnumToString(InventoryMode, mode) + ") got juncture");
  1453. }
  1454. #endif
  1455. return false;
  1456. }
  1457. }
  1458. ScriptInputUserData ctx = new ScriptInputUserData;
  1459. InventoryInputUserData.SerializeMove(ctx, InventoryCommandType.SYNC_MOVE, src, dst);
  1460. GetDayZPlayerOwner().SendSyncJuncture(DayZPlayerSyncJunctures.SJ_INVENTORY, ctx);
  1461. #ifdef ENABLE_LOGGING
  1462. if (LogManager.IsSyncLogEnable())
  1463. {
  1464. syncDebugPrint("[syncinv] " + Object.GetDebugName(GetDayZPlayerOwner()) + " STS = " + GetDayZPlayerOwner().GetSimulationTimeStamp() + " store input for remote - DZPI::Take2Dst(" + typename.EnumToString(InventoryMode, mode) + " server sync move src=" + InventoryLocation.DumpToStringNullSafe(src) + " dst=" + InventoryLocation.DumpToStringNullSafe(dst));
  1465. }
  1466. #endif
  1467. //! Remote inputs are processed in sync juncture once performed on the server - this code below was executing the inventory command before the player simulation timeestamp for remotes which is illegal
  1468. //GetDayZPlayerOwner().StoreInputForRemotes(ctx); // @TODO: is this right place? maybe in HandleInputData(server=true, ...)
  1469. #ifdef ENABLE_LOGGING
  1470. if ( LogManager.IsInventoryMoveLogEnable() )
  1471. {
  1472. Debug.InventoryMoveLog("Success - store input for remote mode - " + typename.EnumToString(InventoryMode, mode) + " src=" + InventoryLocation.DumpToStringNullSafe(src) + " dst=" + InventoryLocation.DumpToStringNullSafe(dst), "n/a" , "n/a", "TakeToDst", GetDayZPlayerOwner().ToString() );
  1473. }
  1474. #endif
  1475. return true;
  1476. case InventoryMode.LOCAL:
  1477. LocationSyncMoveEntity(src, dst);
  1478. return true;
  1479. }
  1480. if (!super.TakeToDst(mode,src,dst))
  1481. {
  1482. return PostDeferredEventTakeToDst(mode,src,dst);
  1483. }
  1484. return true;
  1485. }
  1486. override bool PostDeferredEventTakeToDst(InventoryMode mode, notnull InventoryLocation src, notnull InventoryLocation dst)
  1487. {
  1488. if (!super.PostDeferredEventTakeToDst(mode,src,dst))
  1489. return false;
  1490. if (!m_DeferredEvent)
  1491. {
  1492. m_DeferredEvent = new DeferredTakeToDst(mode,src,dst);
  1493. if (m_DeferredEvent.ReserveInventory(this))
  1494. return true;
  1495. }
  1496. m_DeferredEvent = null;
  1497. return false;
  1498. }
  1499. void HandleTakeToDst( DeferredEvent deferred_event )
  1500. {
  1501. DeferredTakeToDst deferred_take_to_dst = DeferredTakeToDst.Cast(deferred_event);
  1502. if( deferred_take_to_dst )
  1503. {
  1504. #ifdef ENABLE_LOGGING
  1505. if ( LogManager.IsInventoryHFSMLogEnable() )
  1506. {
  1507. Debug.InventoryHFSMLog("STS = " + GetDayZPlayerOwner().GetSimulationTimeStamp(), "n/a" , "n/a", "HandleTakeToDst", GetDayZPlayerOwner().ToString() );
  1508. }
  1509. #endif
  1510. deferred_take_to_dst.ClearInventoryReservation(this);
  1511. if (LogManager.IsInventoryMoveLogEnable())
  1512. {
  1513. inventoryDebugPrint("[inv] I::Take2Dst(" + typename.EnumToString(InventoryMode, deferred_take_to_dst.m_mode) + ") src=" + InventoryLocation.DumpToStringNullSafe(deferred_take_to_dst.m_src) + " dst=" + InventoryLocation.DumpToStringNullSafe(deferred_take_to_dst.m_dst));
  1514. }
  1515. switch (deferred_take_to_dst.m_mode)
  1516. {
  1517. case InventoryMode.PREDICTIVE:
  1518. #ifdef ENABLE_LOGGING
  1519. if (LogManager.IsInventoryHFSMLogEnable())
  1520. {
  1521. Debug.InventoryHFSMLog("PREDICTIVE ", "n/a" , "n/a", "HandleTakeToDst", GetDayZPlayerOwner().ToString() );
  1522. }
  1523. #endif
  1524. if (LocationCanMoveEntity(deferred_take_to_dst.m_src,deferred_take_to_dst.m_dst))
  1525. {
  1526. InventoryInputUserData.SendInputUserDataMove(InventoryCommandType.SYNC_MOVE, deferred_take_to_dst.m_src, deferred_take_to_dst.m_dst);
  1527. LocationSyncMoveEntity(deferred_take_to_dst.m_src, deferred_take_to_dst.m_dst);
  1528. }
  1529. else
  1530. {
  1531. #ifdef ENABLE_LOGGING
  1532. if (LogManager.IsInventoryMoveLogEnable())
  1533. {
  1534. Debug.InventoryMoveLog("Can not move entity (PREDICTIVE) STS = " + GetDayZPlayerOwner().GetSimulationTimeStamp() + " item = " + deferred_take_to_dst.m_dst.GetItem() + " dst=" + InventoryLocation.DumpToStringNullSafe(deferred_take_to_dst.m_dst), "n/a" , "n/a", "HandleTakeToDst", GetDayZPlayerOwner().ToString() );
  1535. }
  1536. #endif
  1537. }
  1538. break;
  1539. case InventoryMode.JUNCTURE:
  1540. #ifdef ENABLE_LOGGING
  1541. if (LogManager.IsInventoryHFSMLogEnable())
  1542. {
  1543. Debug.InventoryHFSMLog("JUNCTURE ", "n/a" , "n/a", "HandleTakeToDst", GetDayZPlayerOwner().ToString());
  1544. }
  1545. #endif
  1546. if (LocationCanMoveEntity(deferred_take_to_dst.m_src, deferred_take_to_dst.m_dst))
  1547. {
  1548. DayZPlayer player = GetGame().GetPlayer();
  1549. player.GetHumanInventory().AddInventoryReservationEx(deferred_take_to_dst.m_dst.GetItem(), deferred_take_to_dst.m_dst, GameInventory.c_InventoryReservationTimeoutShortMS);
  1550. EnableMovableOverride(deferred_take_to_dst.m_dst.GetItem());
  1551. InventoryInputUserData.SendInputUserDataMove(InventoryCommandType.SYNC_MOVE, deferred_take_to_dst.m_src, deferred_take_to_dst.m_dst);
  1552. }
  1553. else
  1554. {
  1555. #ifdef ENABLE_LOGGING
  1556. if (LogManager.IsInventoryMoveLogEnable())
  1557. {
  1558. Debug.InventoryMoveLog("Can not move entity (JUNCTURE) STS = " + GetDayZPlayerOwner().GetSimulationTimeStamp() + " item = " + deferred_take_to_dst.m_dst.GetItem() + " dst=" + InventoryLocation.DumpToStringNullSafe(deferred_take_to_dst.m_dst), "n/a" , "n/a", "HandleTakeToDst", GetDayZPlayerOwner().ToString());
  1559. }
  1560. #endif
  1561. }
  1562. break;
  1563. case InventoryMode.LOCAL:
  1564. #ifdef ENABLE_LOGGING
  1565. if (LogManager.IsInventoryHFSMLogEnable())
  1566. {
  1567. Debug.InventoryHFSMLog("LOCAL ", "n/a" , "n/a", "HandleTakeToDst", GetDayZPlayerOwner().ToString());
  1568. }
  1569. #endif
  1570. break;
  1571. case InventoryMode.SERVER:
  1572. #ifdef ENABLE_LOGGING
  1573. if (LogManager.IsInventoryHFSMLogEnable())
  1574. {
  1575. Debug.InventoryHFSMLog("SERVER ", "n/a" , "n/a", "HandleTakeToDst", GetDayZPlayerOwner().ToString());
  1576. }
  1577. #endif
  1578. break;
  1579. default:
  1580. Error("HandEvent - Invalid mode");
  1581. break;
  1582. }
  1583. }
  1584. }
  1585. override bool SwapEntities (InventoryMode mode, notnull EntityAI item1, notnull EntityAI item2)
  1586. {
  1587. #ifdef ENABLE_LOGGING
  1588. if (LogManager.IsInventoryMoveLogEnable())
  1589. {
  1590. Debug.InventoryMoveLog("STS = " + GetDayZPlayerOwner().GetSimulationTimeStamp() + " item1 = " + item1 + " item2 = " + item2, "n/a" , "n/a", "SwapEntities", GetDayZPlayerOwner().ToString() );
  1591. }
  1592. #endif
  1593. InventoryLocation src1, src2, dst1, dst2;
  1594. if( mode == InventoryMode.LOCAL )
  1595. {
  1596. if (GameInventory.MakeSrcAndDstForSwap(item1, item2, src1, src2, dst1, dst2))
  1597. {
  1598. LocationSwap(src1, src2, dst1, dst2);
  1599. return true;
  1600. }
  1601. }
  1602. if(!super.SwapEntities(mode,item1,item2))
  1603. {
  1604. if (GameInventory.MakeSrcAndDstForSwap(item1, item2, src1, src2, dst1, dst2))
  1605. {
  1606. return PostDeferredForceSwapEntities(mode, item1, item2, dst1, dst2);
  1607. }
  1608. }
  1609. return true;
  1610. }
  1611. override bool PostDeferredForceSwapEntities(InventoryMode mode, notnull EntityAI item1, notnull EntityAI item2, notnull InventoryLocation dst1, notnull InventoryLocation dst2)
  1612. {
  1613. if (!super.PostDeferredForceSwapEntities(mode, item1, item2, dst1, dst2))
  1614. return false;
  1615. if (!m_DeferredEvent)
  1616. {
  1617. m_DeferredEvent = new DeferredForceSwapEntities(mode, item1, item2, dst1, dst2);
  1618. if (m_DeferredEvent.ReserveInventory(this))
  1619. return true;
  1620. }
  1621. m_DeferredEvent = null;
  1622. return false;
  1623. }
  1624. void HandleSwapEntities( DeferredEvent deferred_event )
  1625. {
  1626. DeferredSwapEntities deferred_swap_entities = DeferredSwapEntities.Cast(deferred_event);
  1627. if( deferred_swap_entities )
  1628. {
  1629. deferred_swap_entities.ClearInventoryReservation(this);
  1630. InventoryLocation src1, src2, dst1, dst2;
  1631. if (GameInventory.MakeSrcAndDstForSwap(deferred_swap_entities.m_item1, deferred_swap_entities.m_item2, src1, src2, dst1, dst2))
  1632. {
  1633. if (LogManager.IsInventoryMoveLogEnable())
  1634. {
  1635. inventoryDebugPrint("[inv] I::Swap(" + typename.EnumToString(InventoryMode, deferred_swap_entities.m_mode) + ") src1=" + InventoryLocation.DumpToStringNullSafe(src1) + " src2=" + InventoryLocation.DumpToStringNullSafe(src2) + " dst1=" + InventoryLocation.DumpToStringNullSafe(deferred_swap_entities.m_dst1) + " dst2=" + InventoryLocation.DumpToStringNullSafe(deferred_swap_entities.m_dst2));
  1636. }
  1637. switch (deferred_swap_entities.m_mode)
  1638. {
  1639. case InventoryMode.PREDICTIVE:
  1640. if (CanSwapEntitiesEx(deferred_swap_entities.m_dst1.GetItem(),deferred_swap_entities.m_dst2.GetItem()) )
  1641. {
  1642. InventoryInputUserData.SendInputUserDataSwap(src1, src2, deferred_swap_entities.m_dst1, deferred_swap_entities.m_dst2);
  1643. LocationSwap(src1, src2, deferred_swap_entities.m_dst1, deferred_swap_entities.m_dst2);
  1644. }
  1645. else
  1646. {
  1647. #ifdef ENABLE_LOGGING
  1648. if (LogManager.IsInventoryMoveLogEnable())
  1649. {
  1650. Debug.InventoryMoveLog("Can not swap (PREDICTIVE) STS = " + GetDayZPlayerOwner().GetSimulationTimeStamp() + " item1 = " + deferred_swap_entities.m_dst1.GetItem() + " item2 = " + deferred_swap_entities.m_dst2.GetItem() + " dst=" + InventoryLocation.DumpToStringNullSafe(deferred_swap_entities.m_dst2), "n/a" , "n/a", "ForceSwapEntities", GetDayZPlayerOwner().ToString() );
  1651. }
  1652. #endif
  1653. }
  1654. break;
  1655. case InventoryMode.JUNCTURE:
  1656. if (CanSwapEntitiesEx(deferred_swap_entities.m_dst1.GetItem(),deferred_swap_entities.m_dst2.GetItem()) )
  1657. {
  1658. DayZPlayer player = GetGame().GetPlayer();
  1659. player.GetHumanInventory().AddInventoryReservationEx(deferred_swap_entities.m_dst1.GetItem(), deferred_swap_entities.m_dst1, GameInventory.c_InventoryReservationTimeoutShortMS);
  1660. player.GetHumanInventory().AddInventoryReservationEx(deferred_swap_entities.m_dst2.GetItem(), deferred_swap_entities.m_dst2, GameInventory.c_InventoryReservationTimeoutShortMS);
  1661. EnableMovableOverride(deferred_swap_entities.m_dst1.GetItem());
  1662. EnableMovableOverride(deferred_swap_entities.m_dst2.GetItem());
  1663. InventoryInputUserData.SendInputUserDataSwap(src1, src2, deferred_swap_entities.m_dst1, deferred_swap_entities.m_dst2);
  1664. }
  1665. else
  1666. {
  1667. #ifdef ENABLE_LOGGING
  1668. if (LogManager.IsInventoryMoveLogEnable())
  1669. {
  1670. Debug.InventoryMoveLog("Can not swap (JUNCTURE) STS = " + GetDayZPlayerOwner().GetSimulationTimeStamp() + " item1 = " + deferred_swap_entities.m_dst1.GetItem() + " item2 = " + deferred_swap_entities.m_dst2.GetItem() + " dst=" + InventoryLocation.DumpToStringNullSafe(deferred_swap_entities.m_dst2), "n/a" , "n/a", "ForceSwapEntities", GetDayZPlayerOwner().ToString() );
  1671. }
  1672. #endif
  1673. }
  1674. break;
  1675. case InventoryMode.LOCAL:
  1676. break;
  1677. default:
  1678. Error("SwapEntities - HandEvent - Invalid mode");
  1679. }
  1680. }
  1681. else
  1682. Error("SwapEntities - MakeSrcAndDstForSwap - no inv loc");
  1683. }
  1684. }
  1685. override bool ForceSwapEntities (InventoryMode mode, notnull EntityAI item1, notnull EntityAI item2, notnull InventoryLocation item2_dst)
  1686. {
  1687. #ifdef ENABLE_LOGGING
  1688. if (LogManager.IsInventoryMoveLogEnable())
  1689. {
  1690. Debug.InventoryMoveLog("STS = " + GetDayZPlayerOwner().GetSimulationTimeStamp() + " item1 = " + item1 + " item2 = " + item2 + " dst=" + InventoryLocation.DumpToStringNullSafe(item2_dst), "n/a" , "n/a", "ForceSwapEntities", GetDayZPlayerOwner().ToString() );
  1691. }
  1692. #endif
  1693. InventoryLocation src1, src2, dst1;
  1694. if( mode == InventoryMode.LOCAL )
  1695. {
  1696. if (GameInventory.MakeSrcAndDstForForceSwap(item1, item2, src1, src2, dst1, item2_dst))
  1697. {
  1698. LocationSwap(src1, src2, dst1, item2_dst);
  1699. return true;
  1700. }
  1701. }
  1702. if(!super.ForceSwapEntities(mode,item1,item2,item2_dst))
  1703. {
  1704. if (GameInventory.MakeSrcAndDstForForceSwap(item1, item2, src1, src2, dst1, item2_dst))
  1705. {
  1706. return PostDeferredForceSwapEntities(mode, item1, item2, dst1, item2_dst);
  1707. }
  1708. }
  1709. return true;
  1710. }
  1711. void HandleForceSwapEntities( DeferredEvent deferred_event )
  1712. {
  1713. DeferredForceSwapEntities deferred_force_swap_entities = DeferredForceSwapEntities.Cast(deferred_event);
  1714. if (deferred_force_swap_entities)
  1715. {
  1716. deferred_force_swap_entities.ClearInventoryReservation(this);
  1717. InventoryLocation src1 = new InventoryLocation;
  1718. InventoryLocation src2 = new InventoryLocation;
  1719. deferred_force_swap_entities.m_item1.GetInventory().GetCurrentInventoryLocation(src1);
  1720. deferred_force_swap_entities.m_item2.GetInventory().GetCurrentInventoryLocation(src2);
  1721. DayZPlayer player = GetGame().GetPlayer();
  1722. if (LogManager.IsInventoryMoveLogEnable())
  1723. {
  1724. inventoryDebugPrint("[inv] I::FSwap(" + typename.EnumToString(InventoryMode, deferred_force_swap_entities.m_mode) + ") src1=" + InventoryLocation.DumpToStringNullSafe(src1) + " src2=" + InventoryLocation.DumpToStringNullSafe(src2) + " dst1=" + InventoryLocation.DumpToStringNullSafe(deferred_force_swap_entities.m_dst1) + " dst2=" + InventoryLocation.DumpToStringNullSafe(deferred_force_swap_entities.m_dst2));
  1725. }
  1726. switch (deferred_force_swap_entities.m_mode)
  1727. {
  1728. case InventoryMode.PREDICTIVE:
  1729. if (CanForceSwapEntitiesEx(deferred_force_swap_entities.m_dst1.GetItem(),deferred_force_swap_entities.m_dst1,deferred_force_swap_entities.m_dst2.GetItem(), deferred_force_swap_entities.m_dst2))
  1730. {
  1731. InventoryInputUserData.SendInputUserDataSwap(src1, src2, deferred_force_swap_entities.m_dst1, deferred_force_swap_entities.m_dst2);
  1732. LocationSwap(src1, src2, deferred_force_swap_entities.m_dst1, deferred_force_swap_entities.m_dst2);
  1733. }
  1734. else
  1735. {
  1736. #ifdef ENABLE_LOGGING
  1737. if (LogManager.IsInventoryMoveLogEnable())
  1738. {
  1739. Debug.InventoryMoveLog("Can not force swap (PREDICTIVE) STS = " + GetDayZPlayerOwner().GetSimulationTimeStamp() + " item1 = " + deferred_force_swap_entities.m_dst1.GetItem() + " item2 = " + deferred_force_swap_entities.m_dst2.GetItem() + " dst=" + InventoryLocation.DumpToStringNullSafe(deferred_force_swap_entities.m_dst2), "n/a" , "n/a", "ForceSwapEntities", GetDayZPlayerOwner().ToString());
  1740. }
  1741. #endif
  1742. }
  1743. break;
  1744. case InventoryMode.JUNCTURE:
  1745. if (CanForceSwapEntitiesEx(deferred_force_swap_entities.m_dst1.GetItem(), deferred_force_swap_entities.m_dst1, deferred_force_swap_entities.m_dst2.GetItem(), deferred_force_swap_entities.m_dst2))
  1746. {
  1747. player.GetHumanInventory().AddInventoryReservationEx(deferred_force_swap_entities.m_item1, deferred_force_swap_entities.m_dst1, GameInventory.c_InventoryReservationTimeoutShortMS);
  1748. player.GetHumanInventory().AddInventoryReservationEx(deferred_force_swap_entities.m_item2, deferred_force_swap_entities.m_dst2, GameInventory.c_InventoryReservationTimeoutShortMS);
  1749. InventoryInputUserData.SendInputUserDataSwap(src1, src2, deferred_force_swap_entities.m_dst1, deferred_force_swap_entities.m_dst2);
  1750. }
  1751. else
  1752. {
  1753. #ifdef ENABLE_LOGGING
  1754. if (LogManager.IsInventoryMoveLogEnable())
  1755. {
  1756. Debug.InventoryMoveLog("Can not force swap (JUNCTURE) STS = " + GetDayZPlayerOwner().GetSimulationTimeStamp() + " item1 = " + deferred_force_swap_entities.m_dst1.GetItem() + " item2 = " + deferred_force_swap_entities.m_dst2.GetItem() + " dst=" + InventoryLocation.DumpToStringNullSafe(deferred_force_swap_entities.m_dst2), "n/a" , "n/a", "ForceSwapEntities", GetDayZPlayerOwner().ToString());
  1757. }
  1758. #endif
  1759. }
  1760. break;
  1761. case InventoryMode.LOCAL:
  1762. break;
  1763. default:
  1764. Error("ForceSwapEntities - HandEvent - Invalid mode");
  1765. }
  1766. }
  1767. }
  1768. static void SendServerHandEventViaJuncture (notnull DayZPlayer player, HandEventBase e)
  1769. {
  1770. if (GetGame().IsServer())
  1771. {
  1772. if (e.IsServerSideOnly())
  1773. {
  1774. Error("[syncinv] " + Object.GetDebugName(player) + " SendServerHandEventViaJuncture - called on server side event only, e=" + e.DumpToString());
  1775. }
  1776. if (player.IsAlive())
  1777. {
  1778. InventoryLocation dst = e.GetDst();
  1779. InventoryLocation src = e.GetSrc();
  1780. if (src.IsValid() && dst.IsValid())
  1781. {
  1782. if (player.NeedInventoryJunctureFromServer(src.GetItem(), src.GetParent(), dst.GetParent()))
  1783. {
  1784. #ifdef ENABLE_LOGGING
  1785. if (LogManager.IsSyncLogEnable())
  1786. {
  1787. syncDebugPrint("[syncinv] " + Object.GetDebugName(player) + " STS = " + player.GetSimulationTimeStamp() + " SendServerHandEventViaJuncture(" + typename.EnumToString(InventoryMode, InventoryMode.SERVER) + ") need juncture src=" + InventoryLocation.DumpToStringNullSafe(src) + " dst=" + InventoryLocation.DumpToStringNullSafe(dst));
  1788. }
  1789. #endif
  1790. if (GetGame().AddInventoryJunctureEx(player, src.GetItem(), dst, true, GameInventory.c_InventoryReservationTimeoutMS))
  1791. {
  1792. #ifdef ENABLE_LOGGING
  1793. if (LogManager.IsSyncLogEnable())
  1794. {
  1795. syncDebugPrint("[syncinv] " + Object.GetDebugName(player) + " STS = " + player.GetSimulationTimeStamp() + " SendServerHandEventViaJuncture(" + typename.EnumToString(InventoryMode, InventoryMode.SERVER) + ") got juncture");
  1796. }
  1797. #endif
  1798. }
  1799. else
  1800. {
  1801. #ifdef ENABLE_LOGGING
  1802. if (LogManager.IsSyncLogEnable())
  1803. {
  1804. syncDebugPrint("[syncinv] " + Object.GetDebugName(player) + " STS = " + player.GetSimulationTimeStamp() + " SendServerHandEventViaJuncture(" + typename.EnumToString(InventoryMode, InventoryMode.SERVER) + ") !got juncture");
  1805. }
  1806. #endif
  1807. }
  1808. }
  1809. #ifdef ENABLE_LOGGING
  1810. if (LogManager.IsSyncLogEnable())
  1811. {
  1812. syncDebugPrint("[syncinv] " + Object.GetDebugName(player) + " STS = " + player.GetSimulationTimeStamp() + " SendServerHandEventViaJuncture(" + typename.EnumToString(InventoryMode, InventoryMode.SERVER) + " server hand event src=" + InventoryLocation.DumpToStringNullSafe(src) + " dst=" + InventoryLocation.DumpToStringNullSafe(dst));
  1813. }
  1814. #endif
  1815. ScriptInputUserData ctx = new ScriptInputUserData;
  1816. InventoryInputUserData.SerializeHandEvent(ctx, e);
  1817. player.SendSyncJuncture(DayZPlayerSyncJunctures.SJ_INVENTORY, ctx);
  1818. #ifdef ENABLE_LOGGING
  1819. if (LogManager.IsSyncLogEnable())
  1820. {
  1821. syncDebugPrint("[syncinv] " + Object.GetDebugName(player) + " STS = " + player.GetSimulationTimeStamp() + " store input for remote - SendServerHandEventViaJuncture(" + typename.EnumToString(InventoryMode, InventoryMode.SERVER) + " server hand event src=" + InventoryLocation.DumpToStringNullSafe(src) + " dst=" + InventoryLocation.DumpToStringNullSafe(dst));
  1822. }
  1823. #endif
  1824. //! Remote inputs are processed in sync juncture once performed on the server - this code below was executing the inventory command before the player simulation timeestamp for remotes which is illegal
  1825. //player.StoreInputForRemotes(ctx); // @TODO: is this right place? maybe in HandleInputData(server=true, ...)
  1826. }
  1827. }
  1828. else
  1829. {
  1830. Error("[syncinv] SendServerHandEventViaJuncture - called on dead player, juncture is for living only");
  1831. }
  1832. }
  1833. }
  1834. /**@fn NetSyncCurrentStateID
  1835. * @brief Engine callback - network synchronization of FSM's state. not intended to direct use.
  1836. **/
  1837. override void NetSyncCurrentStateID (int id)
  1838. {
  1839. super.NetSyncCurrentStateID(id);
  1840. GetDayZPlayerOwner().GetItemAccessor().OnItemInHandsChanged();
  1841. }
  1842. /**@fn OnAfterStoreLoad
  1843. * @brief engine reaction to load from database
  1844. * originates in:
  1845. * engine - Person::BinLoad
  1846. * script - PlayerBase.OnAfterStoreLoad
  1847. **/
  1848. override void OnAfterStoreLoad ()
  1849. {
  1850. GetDayZPlayerOwner().GetItemAccessor().OnItemInHandsChanged(true);
  1851. }
  1852. /**@fn OnEventForRemoteWeapon
  1853. * @brief reaction of remote weapon to (common user/anim/...) event sent from server
  1854. **/
  1855. bool OnEventForRemoteWeapon (ParamsReadContext ctx)
  1856. {
  1857. if (GetEntityInHands())
  1858. {
  1859. Weapon_Base wpn = Weapon_Base.Cast(GetEntityInHands());
  1860. if (wpn)
  1861. {
  1862. PlayerBase pb = PlayerBase.Cast(GetDayZPlayerOwner());
  1863. WeaponEventBase e = CreateWeaponEventFromContext(ctx);
  1864. if (pb && e)
  1865. {
  1866. pb.GetWeaponManager().SetRunning(true);
  1867. if (LogManager.IsWeaponLogEnable())
  1868. {
  1869. fsmDebugSpam("[wpnfsm] " + Object.GetDebugName(wpn) + " recv event from remote: created event=" + e);
  1870. }
  1871. if (e.GetEventID() == WeaponEventID.HUMANCOMMAND_ACTION_ABORTED)
  1872. {
  1873. wpn.ProcessWeaponAbortEvent(e);
  1874. }
  1875. else
  1876. {
  1877. wpn.ProcessWeaponEvent(e);
  1878. }
  1879. pb.GetWeaponManager().SetRunning(false);
  1880. }
  1881. }
  1882. else
  1883. Error("OnEventForRemoteWeapon - entity in hands, but not weapon. item=" + GetEntityInHands());
  1884. }
  1885. else
  1886. Error("OnEventForRemoteWeapon - no entity in hands");
  1887. return true;
  1888. }
  1889. /**@fn OnHandEventForRemote
  1890. * @brief reaction of remote weapon to (common user/anim/...) event sent from server
  1891. **/
  1892. bool OnHandEventForRemote (ParamsReadContext ctx)
  1893. {
  1894. HandEventBase e = HandEventBase.CreateHandEventFromContext(ctx);
  1895. if (e)
  1896. {
  1897. if (LogManager.IsInventoryHFSMLogEnable())
  1898. {
  1899. hndDebugSpam("[hndfsm] recv event from remote: created event=" + e);
  1900. }
  1901. //m_FSM.ProcessEvent(e);
  1902. if (e.GetEventID() == HandEventID.HUMANCOMMAND_ACTION_ABORTED)
  1903. {
  1904. ProcessEventResult aa;
  1905. m_FSM.ProcessAbortEvent(e, aa);
  1906. }
  1907. else
  1908. {
  1909. m_FSM.ProcessEvent(e);
  1910. }
  1911. return true;
  1912. }
  1913. return false;
  1914. }
  1915. void SyncHandEventToRemote (HandEventBase e)
  1916. {
  1917. DayZPlayer p = GetDayZPlayerOwner();
  1918. if (p && p.GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER)
  1919. {
  1920. ScriptRemoteInputUserData ctx = new ScriptRemoteInputUserData;
  1921. ctx.Write(INPUT_UDT_HAND_REMOTE_EVENT);
  1922. e.WriteToContext(ctx);
  1923. if (LogManager.IsInventoryHFSMLogEnable())
  1924. {
  1925. hndDebugPrint("[hndfsm] send 2 remote: sending e=" + e + " id=" + e.GetEventID() + " p=" + p + " e=" + e.DumpToString());
  1926. }
  1927. p.StoreInputForRemotes(ctx);
  1928. }
  1929. }
  1930. override void OnHandsExitedStableState (HandStateBase src, HandStateBase dst)
  1931. {
  1932. super.OnHandsExitedStableState(src, dst);
  1933. if (LogManager.IsInventoryHFSMLogEnable())
  1934. {
  1935. hndDebugPrint("[hndfsm] hand fsm exit stable src=" + src.Type().ToString());
  1936. }
  1937. }
  1938. override void OnHandsEnteredStableState (HandStateBase src, HandStateBase dst)
  1939. {
  1940. super.OnHandsEnteredStableState(src, dst);
  1941. if (LogManager.IsInventoryHFSMLogEnable())
  1942. {
  1943. hndDebugPrint("[hndfsm] hand fsm entered stable dst=" + dst.Type().ToString());
  1944. }
  1945. }
  1946. override void OnHandsStateChanged (HandStateBase src, HandStateBase dst)
  1947. {
  1948. super.OnHandsStateChanged(src, dst);
  1949. if (LogManager.IsInventoryHFSMLogEnable())
  1950. {
  1951. hndDebugPrint("[hndfsm] hand fsm changed state src=" + src.Type().ToString() + " ---> dst=" + dst.Type().ToString());
  1952. }
  1953. if (src.IsIdle())
  1954. OnHandsExitedStableState(src, dst);
  1955. if (dst.IsIdle())
  1956. OnHandsEnteredStableState(src, dst);
  1957. #ifdef DIAG_DEVELOPER
  1958. PlayerBase p = PlayerBase.Cast(GetDayZPlayerOwner());
  1959. if (p && p.m_Bot)
  1960. {
  1961. p.m_Bot.ProcessEvent(new BotEventOnItemInHandsChanged(p));
  1962. }
  1963. #endif
  1964. }
  1965. override bool HandEvent(InventoryMode mode, HandEventBase e)
  1966. {
  1967. if (!IsProcessing())
  1968. {
  1969. EntityAI itemInHands = GetEntityInHands();
  1970. InventoryLocation handInventoryLocation();
  1971. handInventoryLocation.SetHands(GetInventoryOwner(), itemInHands);
  1972. InventoryValidation validation();
  1973. if (e.CanPerformEventEx(validation))
  1974. {
  1975. m_DeferredEvent = new DeferredHandEvent(mode, e);
  1976. if (m_DeferredEvent.ReserveInventory(this))
  1977. {
  1978. return true;
  1979. }
  1980. }
  1981. m_DeferredEvent = null;
  1982. //! Let the client know a failure happened
  1983. if (!GetGame().IsMultiplayer() || GetGame().IsClient())
  1984. {
  1985. //! If singleplayer or the client is executing this
  1986. OnInventoryFailure(InventoryCommandType.HAND_EVENT, validation.m_Reason, e.GetSrc(), e.GetDst());
  1987. }
  1988. else
  1989. {
  1990. ScriptInputUserData serializer();
  1991. InventoryInputUserData.SerializeHandEvent(serializer, e);
  1992. serializer.Write(validation.m_Reason);
  1993. GetDayZPlayerOwner().SendSyncJuncture(DayZPlayerSyncJunctures.SJ_INVENTORY_FAILURE, serializer);
  1994. }
  1995. }
  1996. return false;
  1997. }
  1998. void HandleHandEvent(DeferredEvent deferred_event)
  1999. {
  2000. //! Default structure suffices
  2001. InventoryValidation validation();
  2002. DeferredHandEvent deferred_hand_event = DeferredHandEvent.Cast(deferred_event);
  2003. if (deferred_hand_event)
  2004. {
  2005. #ifdef ENABLE_LOGGING
  2006. if (LogManager.IsInventoryHFSMLogEnable())
  2007. {
  2008. Debug.InventoryHFSMLog("STS = " + GetDayZPlayerOwner().GetSimulationTimeStamp(), "n/a" , "n/a", "HandleHandEvent", GetDayZPlayerOwner().ToString());
  2009. }
  2010. #endif
  2011. if (LogManager.IsInventoryHFSMLogEnable())
  2012. {
  2013. hndDebugPrint("[inv] HumanInventory::HandEvent(" + typename.EnumToString(InventoryMode, deferred_hand_event.m_mode) + ") ev=" + deferred_hand_event.m_event.DumpToString());
  2014. }
  2015. switch (deferred_hand_event.m_mode)
  2016. {
  2017. case InventoryMode.PREDICTIVE:
  2018. #ifdef ENABLE_LOGGING
  2019. if (LogManager.IsInventoryHFSMLogEnable())
  2020. {
  2021. Debug.InventoryHFSMLog("PREDICTIVE", "n/a" , "n/a", "HandleHandEvent", GetDayZPlayerOwner().ToString());
  2022. }
  2023. #endif
  2024. deferred_hand_event.ClearInventoryReservation(this);
  2025. if (deferred_hand_event.m_event.CanPerformEventEx(validation))
  2026. {
  2027. InventoryInputUserData.SendInputUserDataHandEvent(deferred_hand_event.m_event);
  2028. ProcessHandEvent(deferred_hand_event.m_event);
  2029. }
  2030. break;
  2031. case InventoryMode.JUNCTURE:
  2032. #ifdef ENABLE_LOGGING
  2033. if (LogManager.IsInventoryHFSMLogEnable())
  2034. {
  2035. Debug.InventoryHFSMLog("JUNCTURE", "n/a" , "n/a", "HandleHandEvent", GetDayZPlayerOwner().ToString());
  2036. }
  2037. #endif
  2038. deferred_hand_event.ClearInventoryReservation(this);
  2039. if (deferred_hand_event.m_event.CanPerformEventEx(validation))
  2040. {
  2041. deferred_hand_event.ReserveInventory(this);
  2042. InventoryInputUserData.SendInputUserDataHandEvent(deferred_hand_event.m_event);
  2043. //Functionality to prevent desync when two players perform interfering action at the same time
  2044. EntityAI itemSrc = deferred_hand_event.m_event.GetSrcEntity();
  2045. EntityAI itemDst = null;
  2046. if (deferred_hand_event.m_event.GetDst())
  2047. itemDst = deferred_hand_event.m_event.GetDst().GetItem();
  2048. if (itemSrc)
  2049. EnableMovableOverride(itemSrc);
  2050. if (itemDst)
  2051. EnableMovableOverride(itemDst);
  2052. }
  2053. break;
  2054. case InventoryMode.LOCAL:
  2055. #ifdef ENABLE_LOGGING
  2056. if (LogManager.IsInventoryHFSMLogEnable())
  2057. {
  2058. Debug.InventoryHFSMLog("LOCAL", "n/a" , "n/a", "HandleHandEvent", GetDayZPlayerOwner().ToString());
  2059. }
  2060. #endif
  2061. deferred_hand_event.ClearInventoryReservation(this);
  2062. ProcessHandEvent(deferred_hand_event.m_event);
  2063. //PostHandEvent(deferred_hand_event.m_event);
  2064. break;
  2065. case InventoryMode.SERVER:
  2066. #ifdef ENABLE_LOGGING
  2067. if (LogManager.IsInventoryHFSMLogEnable())
  2068. {
  2069. Debug.InventoryHFSMLog("SERVER", "n/a" , "n/a", "HandleHandEvent", GetDayZPlayerOwner().ToString());
  2070. }
  2071. if (LogManager.IsInventoryHFSMLogEnable())
  2072. {
  2073. hndDebugPrint("[inv] DZPI::HandEvent(" + typename.EnumToString(InventoryMode, deferred_hand_event.m_mode) + ")");
  2074. }
  2075. #endif
  2076. if (!deferred_hand_event.m_event.IsServerSideOnly())
  2077. {
  2078. if (GetDayZPlayerOwner().IsAlive())
  2079. {
  2080. SendServerHandEventViaJuncture(GetDayZPlayerOwner(), deferred_hand_event.m_event);
  2081. }
  2082. else
  2083. {
  2084. InventoryInputUserData.SendServerHandEventViaInventoryCommand(GetDayZPlayerOwner(), deferred_hand_event.m_event);
  2085. }
  2086. }
  2087. else
  2088. {
  2089. ProcessHandEvent(deferred_hand_event.m_event);
  2090. }
  2091. break;
  2092. default:
  2093. Error("HumanInventory::HandEvent - Invalid mode");
  2094. }
  2095. }
  2096. }
  2097. override void HandleInventoryManipulation()
  2098. {
  2099. super.HandleInventoryManipulation();
  2100. if(m_DeferredEvent && ScriptInputUserData.CanStoreInputUserData() )
  2101. {
  2102. HandleHandEvent(m_DeferredEvent);
  2103. HandleTakeToDst(m_DeferredEvent);
  2104. HandleSwapEntities(m_DeferredEvent);
  2105. HandleForceSwapEntities(m_DeferredEvent);
  2106. m_DeferredEvent = null;
  2107. }
  2108. }
  2109. bool IsProcessing()
  2110. {
  2111. return !m_FSM.GetCurrentState().IsIdle() || m_DeferredEvent || m_DeferredPostedHandEvent;
  2112. }
  2113. bool PlayerCheckRequestSrc ( notnull InventoryLocation src, float radius )
  2114. {
  2115. bool result = true;
  2116. EntityAI ent = src.GetParent();
  2117. if ( ent )
  2118. {
  2119. PlayerBase player = PlayerBase.Cast(ent.GetHierarchyRootPlayer());
  2120. if (player)
  2121. {
  2122. if ( GetDayZPlayerOwner() != player )
  2123. {
  2124. if (player.IsAlive())
  2125. {
  2126. if (!player.IsRestrained() && !player.IsUnconscious())
  2127. {
  2128. return false;
  2129. }
  2130. }
  2131. }
  2132. }
  2133. }
  2134. if ( result )
  2135. {
  2136. result = CheckRequestSrc( GetManOwner(), src, radius);
  2137. }
  2138. return result;
  2139. }
  2140. bool PlayerCheckRequestDst ( notnull InventoryLocation src, notnull InventoryLocation dst, float radius )
  2141. {
  2142. bool result = true;
  2143. EntityAI ent = dst.GetParent();
  2144. if ( ent )
  2145. {
  2146. PlayerBase player = PlayerBase.Cast(ent.GetHierarchyRootPlayer());
  2147. if (player)
  2148. {
  2149. if ( GetDayZPlayerOwner() != player )
  2150. {
  2151. if (player.IsAlive())
  2152. {
  2153. if (!player.IsRestrained() && !player.IsUnconscious())
  2154. {
  2155. return false;
  2156. }
  2157. }
  2158. }
  2159. }
  2160. }
  2161. if ( result )
  2162. {
  2163. result = CheckMoveToDstRequest( GetManOwner(), src, dst, radius);
  2164. }
  2165. return result;
  2166. }
  2167. bool PlayerCheckSwapItemsRequest( notnull InventoryLocation src1, notnull InventoryLocation src2, notnull InventoryLocation dst1, notnull InventoryLocation dst2, float radius)
  2168. {
  2169. bool result = true;
  2170. EntityAI ent = dst1.GetParent();
  2171. PlayerBase player;
  2172. if ( ent )
  2173. {
  2174. player = PlayerBase.Cast(ent.GetHierarchyRootPlayer());
  2175. if (player)
  2176. {
  2177. if ( GetDayZPlayerOwner() != player )
  2178. {
  2179. if (player.IsAlive())
  2180. {
  2181. if (!player.IsRestrained() && !player.IsUnconscious())
  2182. {
  2183. return false;
  2184. }
  2185. }
  2186. }
  2187. }
  2188. }
  2189. ent = dst2.GetParent();
  2190. if ( ent )
  2191. {
  2192. player = PlayerBase.Cast(ent.GetHierarchyRootPlayer());
  2193. if (player)
  2194. {
  2195. if ( GetDayZPlayerOwner() != player )
  2196. {
  2197. if (player.IsAlive())
  2198. {
  2199. if (!player.IsRestrained() && !player.IsUnconscious())
  2200. {
  2201. return false;
  2202. }
  2203. }
  2204. }
  2205. }
  2206. }
  2207. if ( result )
  2208. {
  2209. result = CheckSwapItemsRequest( GetManOwner(), src1, src2, dst1, dst2, GameInventory.c_MaxItemDistanceRadius);
  2210. }
  2211. return result;
  2212. }
  2213. bool PlayerCheckDropRequest ( notnull InventoryLocation src, float radius )
  2214. {
  2215. bool result = true;
  2216. EntityAI ent = src.GetParent();
  2217. if ( ent )
  2218. {
  2219. PlayerBase player = PlayerBase.Cast(ent.GetHierarchyRootPlayer());
  2220. if (player)
  2221. {
  2222. if ( GetDayZPlayerOwner() != player )
  2223. {
  2224. if (player.IsAlive())
  2225. {
  2226. if (!player.IsRestrained() && !player.IsUnconscious())
  2227. {
  2228. return false;
  2229. }
  2230. }
  2231. }
  2232. }
  2233. }
  2234. if ( result )
  2235. {
  2236. result = CheckDropRequest( GetManOwner(), src, radius);
  2237. }
  2238. return result;
  2239. }
  2240. //! Local, checks only stuff that is in guaranteed sync
  2241. bool MoveCheckExclusionMaskLocal ( notnull InventoryLocation src, notnull InventoryLocation dst)
  2242. {
  2243. if (dst.GetType() == InventoryLocationType.ATTACHMENT)
  2244. {
  2245. return dst.GetParent().CheckAttachmentReceiveExclusion(src.GetItem(),dst.GetSlot());
  2246. }
  2247. return true;
  2248. }
  2249. //! Local, checks only stuff that is in guaranteed sync
  2250. bool SwapCheckExclusionMaskLocal ( notnull InventoryLocation src1, notnull InventoryLocation src2, notnull InventoryLocation dst1, notnull InventoryLocation dst2)
  2251. {
  2252. bool failed = false;
  2253. if (dst1.GetType() == InventoryLocationType.ATTACHMENT)
  2254. {
  2255. failed |= !dst1.GetParent().CheckAttachmentReceiveExclusion(dst1.GetItem(),dst1.GetSlot());
  2256. }
  2257. if (dst2.GetType() == InventoryLocationType.ATTACHMENT)
  2258. {
  2259. failed |= !dst2.GetParent().CheckAttachmentReceiveExclusion(dst2.GetItem(),dst2.GetSlot());
  2260. }
  2261. return !failed;
  2262. }
  2263. //! DEPRECATED
  2264. bool ValidateDestroy(inout Serializer ctx, InventoryValidation validation)
  2265. {
  2266. InventoryCommandType type = InventoryCommandType.DESTROY;
  2267. if (validation.m_IsJuncture)
  2268. {
  2269. /** TODO(kumarjac):
  2270. * Probably should be called through inventory juncture,
  2271. * we shouldn't allow the client to delete until the
  2272. * server says it is okay as there can be more reasons
  2273. * than "cheater" for it to be rejected such as desync
  2274. */
  2275. return true;
  2276. }
  2277. InventoryLocation src = new InventoryLocation;
  2278. src.ReadFromContext(ctx);
  2279. #ifdef ENABLE_LOGGING
  2280. if (LogManager.IsInventoryMoveLogEnable())
  2281. {
  2282. Debug.InventoryMoveLog("STS = " + GetDayZPlayerOwner().GetSimulationTimeStamp() + " src=" + InventoryLocation.DumpToStringNullSafe(src), "DESTROY" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  2283. }
  2284. #endif
  2285. if (validation.m_IsRemote && !src.GetItem())
  2286. {
  2287. #ifdef ENABLE_LOGGING
  2288. if (LogManager.IsInventoryMoveLogEnable())
  2289. {
  2290. Debug.InventoryMoveLog("Failed item not exist", "DESTROY" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  2291. }
  2292. #endif
  2293. Error("[syncinv] HandleInputData remote input (cmd=DESTROY) dropped, item not in bubble");
  2294. return true;
  2295. }
  2296. //! Do not check for action validity on remotes or when performing through juncture.
  2297. //! Juncture locks guarentee the item is safe to interact with and the server has validated the command at this point.
  2298. //! Checking at this point is both wasteful and can result in a failure which leads to desync
  2299. if (!validation.m_IsRemote && !validation.m_IsJuncture && !PlayerCheckRequestSrc(src, GameInventory.c_MaxItemDistanceRadius))
  2300. {
  2301. #ifdef ENABLE_LOGGING
  2302. if (LogManager.IsInventoryMoveLogEnable())
  2303. {
  2304. Debug.InventoryMoveLog("Failed CheckRequestSrc", "DESTROY" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  2305. }
  2306. #endif
  2307. return true;
  2308. }
  2309. //! Do not check for action validity on remotes or when performing through juncture.
  2310. //! Juncture locks guarentee the item is safe to interact with and the server has validated the command at this point.
  2311. //! Checking at this point is both wasteful and can result in a failure which leads to desync
  2312. if (!validation.m_IsRemote && !validation.m_IsJuncture && !PlayerCheckDropRequest(src, GameInventory.c_MaxItemDistanceRadius))
  2313. {
  2314. #ifdef ENABLE_LOGGING
  2315. if (LogManager.IsInventoryMoveLogEnable())
  2316. {
  2317. Debug.InventoryMoveLog("Failed CheckDropRequest", "DESTROY" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  2318. }
  2319. #endif
  2320. return true;
  2321. }
  2322. #ifdef ENABLE_LOGGING
  2323. if (LogManager.IsInventoryMoveLogEnable())
  2324. {
  2325. Debug.InventoryMoveLog("Success ObjectDelete", "DESTROY" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  2326. }
  2327. #endif
  2328. GetGame().ObjectDelete(src.GetItem());
  2329. validation.m_Result = InventoryValidationResult.SUCCESS;
  2330. return true;
  2331. }
  2332. }