dayzplayerinventory.c 87 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656
  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. break;
  531. }
  532. case InventoryCommandType.HAND_EVENT:
  533. {
  534. HandEventBase e = HandEventBase.CreateHandEventFromContext(ctx);
  535. src = e.GetSrc();
  536. dst = e.GetDst();
  537. break;
  538. }
  539. case InventoryCommandType.SWAP:
  540. {
  541. src.ReadFromContext(ctx);
  542. temp.ReadFromContext(ctx);
  543. dst.ReadFromContext(ctx);
  544. temp.ReadFromContext(ctx);
  545. break;
  546. }
  547. case InventoryCommandType.FORCESWAP:
  548. {
  549. break;
  550. }
  551. case InventoryCommandType.DESTROY:
  552. {
  553. src.ReadFromContext(ctx);
  554. break;
  555. }
  556. }
  557. InventoryValidationReason reason;
  558. if (!ctx.Read(reason))
  559. {
  560. reason = InventoryValidationReason.UNKNOWN;
  561. }
  562. OnInventoryFailure(type, reason, src, dst);
  563. }
  564. override void OnInventoryFailure(InventoryCommandType type, InventoryValidationReason reason, InventoryLocation src, InventoryLocation dst)
  565. {
  566. if (reason == InventoryValidationReason.DROP_PREVENTED)
  567. {
  568. //! TODO(kumarjac): Notify player here
  569. return;
  570. }
  571. }
  572. /**@fn OnHandleStoredJunctureData
  573. * @brief reaction to engine callback
  574. * originates in engine - DayZPlayerInventory::HandleStoredJunctureData
  575. **/
  576. protected void OnHandleStoredJunctureData(ParamsReadContext ctx)
  577. {
  578. int tmp = -1;
  579. ctx.Read(tmp);
  580. #ifdef ENABLE_LOGGING
  581. if (LogManager.IsSyncLogEnable())
  582. {
  583. syncDebugPrint("[syncinv] " + Object.GetDebugName(GetDayZPlayerOwner()) + " handle JunctureData packet STS = " + GetDayZPlayerOwner().GetSimulationTimeStamp());
  584. }
  585. #endif
  586. //! Juncture is only ever Server Req->Client Ack and Perform->Server Perform, never remote
  587. ProcessInputData(ctx, true, false);
  588. }
  589. /**@fn StoreJunctureData
  590. * @brief stores received input user data for later handling
  591. /aaa
  592. **/
  593. proto native void StoreJunctureData(ParamsReadContext ctx);
  594. ///@} juncture
  595. ///@{ input user data
  596. /**@fn OnInputUserDataProcess
  597. * @brief reaction to engine callback
  598. * originates in:
  599. * engine - DayZPlayer::OnInputUserDataReceived
  600. * script - DayZPlayerImplement.OnInputUserDataReceived
  601. **/
  602. override bool OnInputUserDataProcess(ParamsReadContext ctx)
  603. {
  604. #ifdef ENABLE_LOGGING
  605. if (LogManager.IsSyncLogEnable())
  606. {
  607. syncDebugPrint("[syncinv] " + Object.GetDebugName(GetDayZPlayerOwner()) + " store InputUserData packet STS = " + GetDayZPlayerOwner().GetSimulationTimeStamp());
  608. }
  609. #endif
  610. StoreInputUserData(ctx);
  611. return true;
  612. }
  613. /**@fn OnHandleStoredInputUserData
  614. * @brief reaction to engine callback
  615. * originates in engine - DayZPlayerInventory::HandleStoredInputUserData
  616. **/
  617. protected void OnHandleStoredInputUserData(ParamsReadContext ctx)
  618. {
  619. int tmp = -1;
  620. ctx.Read(tmp);
  621. #ifdef ENABLE_LOGGING
  622. if (LogManager.IsSyncLogEnable())
  623. {
  624. syncDebugPrint("[syncinv] " + Object.GetDebugName(GetDayZPlayerOwner()) + " handle InputUserData packet STS = " + GetDayZPlayerOwner().GetSimulationTimeStamp());
  625. }
  626. #endif
  627. ProcessInputData(ctx, false, false);
  628. }
  629. /**@fn StoreInputUserData
  630. * @brief stores received input user data for later handling
  631. **/
  632. proto native void StoreInputUserData(ParamsReadContext ctx);
  633. ///@} input user data
  634. void OnInputUserDataForRemote(ParamsReadContext ctx)
  635. {
  636. #ifdef ENABLE_LOGGING
  637. if (LogManager.IsSyncLogEnable())
  638. {
  639. syncDebugPrint("[syncinv] " + Object.GetDebugName(GetDayZPlayerOwner()) + " remote handling InputUserData packet from server");
  640. }
  641. #endif
  642. ProcessInputData(ctx, false, true);
  643. }
  644. override void OnServerInventoryCommand(ParamsReadContext ctx)
  645. {
  646. #ifdef ENABLE_LOGGING
  647. if (LogManager.IsSyncLogEnable())
  648. {
  649. syncDebugPrint("[syncinv] " + Object.GetDebugName(GetDayZPlayerOwner()) + " DZPInventory command from server");
  650. }
  651. #endif
  652. ProcessInputData(ctx, true, true);
  653. }
  654. bool ValidateSyncMove(inout Serializer ctx, InventoryValidation validation)
  655. {
  656. InventoryCommandType type = InventoryCommandType.SYNC_MOVE;
  657. InventoryLocation src = new InventoryLocation;
  658. InventoryLocation dst = new InventoryLocation;
  659. bool success = true;
  660. src.ReadFromContext(ctx);
  661. dst.ReadFromContext(ctx);
  662. #ifdef ENABLE_LOGGING
  663. if (LogManager.IsInventoryMoveLogEnable())
  664. {
  665. Debug.InventoryMoveLog("STS = " + GetDayZPlayerOwner().GetSimulationTimeStamp() + "src=" + InventoryLocation.DumpToStringNullSafe(src) + " dst=" + InventoryLocation.DumpToStringNullSafe(dst), "SYNC_MOVE" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  666. }
  667. #endif
  668. if (validation.m_IsRemote && (!src.GetItem() || !dst.GetItem()))
  669. {
  670. //! kumarjac: This indicates a failure in replication relationships as player full inventory should be synchronized always if player exists on the remote
  671. #ifdef ENABLE_LOGGING
  672. if (LogManager.IsInventoryMoveLogEnable())
  673. {
  674. Debug.InventoryMoveLog("Failed - item not in bubble", "SYNC_MOVE" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  675. }
  676. if (LogManager.IsSyncLogEnable())
  677. {
  678. syncDebugPrint("[syncinv] HandleInputData remote input (cmd=SYNC_MOVE) dropped, item not in bubble! src=" + InventoryLocation.DumpToStringNullSafe(src) + " dst=" + InventoryLocation.DumpToStringNullSafe(dst));
  679. }
  680. #endif
  681. return true;
  682. }
  683. EnableMovableOverride(src.GetItem());
  684. //! Do not check for action validity on remotes or when performing through juncture.
  685. //! Juncture locks guarentee the item is safe to interact with and the server has validated the command at this point.
  686. //! Checking at this point is both wasteful and can result in a failure which leads to desync
  687. if (success && !validation.m_IsRemote && !validation.m_IsJuncture && !PlayerCheckRequestSrc(src, GameInventory.c_MaxItemDistanceRadius))
  688. {
  689. //! kumarjac: This indicates a failure in replication relationships as player full inventory should be synchronized always if player exists on the remote
  690. #ifdef ENABLE_LOGGING
  691. if (LogManager.IsInventoryMoveLogEnable())
  692. {
  693. Debug.InventoryMoveLog("Failed - CheckRequestSrc", "SYNC_MOVE" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  694. }
  695. if (LogManager.IsSyncLogEnable())
  696. {
  697. syncDebugPrint("[cheat] HandleInputData man=" + Object.GetDebugName(GetManOwner()) + " failed src check with cmd=" + typename.EnumToString(InventoryCommandType, type) + " src=" + InventoryLocation.DumpToStringNullSafe(src));
  698. }
  699. #endif
  700. RemoveMovableOverride(src.GetItem());
  701. if (GetDayZPlayerOwner().GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER)
  702. {
  703. success = false;
  704. }
  705. else
  706. {
  707. return true;
  708. }
  709. }
  710. //! Do not check for action validity on remotes or when performing through juncture.
  711. //! Juncture locks guarentee the item is safe to interact with and the server has validated the command at this point.
  712. //! Checking at this point is both wasteful and can result in a failure which leads to desync
  713. if (success && !validation.m_IsRemote && !validation.m_IsJuncture && !PlayerCheckRequestDst(src, dst, GameInventory.c_MaxItemDistanceRadius))
  714. {
  715. #ifdef ENABLE_LOGGING
  716. if (LogManager.IsInventoryMoveLogEnable())
  717. {
  718. Debug.InventoryMoveLog("Failed - CheckMoveToDstRequest", "SYNC_MOVE" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  719. }
  720. if (LogManager.IsSyncLogEnable())
  721. {
  722. syncDebugPrint("[cheat] HandleInputData man=" + Object.GetDebugName(GetManOwner()) + " is cheating with cmd=" + typename.EnumToString(InventoryCommandType, type) + " src=" + InventoryLocation.DumpToStringNullSafe(src) + " dst=" + InventoryLocation.DumpToStringNullSafe(dst));
  723. }
  724. #endif
  725. RemoveMovableOverride(src.GetItem());
  726. if (GetDayZPlayerOwner().GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER)
  727. {
  728. success = false;
  729. }
  730. else
  731. {
  732. return true;
  733. }
  734. }
  735. RemoveMovableOverride(src.GetItem());
  736. #ifdef ENABLE_LOGGING
  737. if (LogManager.IsSyncLogEnable())
  738. {
  739. 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));
  740. }
  741. #endif
  742. //! 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
  743. if (!validation.m_IsJuncture && GetDayZPlayerOwner().GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER)
  744. {
  745. JunctureRequestResult result_mv = TryAcquireInventoryJunctureFromServer(GetDayZPlayerOwner(), src, dst);
  746. if (result_mv == JunctureRequestResult.JUNCTURE_NOT_REQUIRED)
  747. {
  748. #ifdef ENABLE_LOGGING
  749. if (LogManager.IsInventoryMoveLogEnable())
  750. {
  751. Debug.InventoryMoveLog("Juncture not required", "SYNC_MOVE" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  752. }
  753. #endif
  754. if (success)
  755. {
  756. //! TODO(kumarjac): We should continue with the execution and not have this special block but making a change here now will require testing
  757. LocationSyncMoveEntity(src, dst);
  758. validation.m_Result = InventoryValidationResult.SUCCESS;
  759. }
  760. return true;
  761. }
  762. else if (success && result_mv == JunctureRequestResult.JUNCTURE_ACQUIRED)
  763. {
  764. #ifdef ENABLE_LOGGING
  765. if (LogManager.IsInventoryMoveLogEnable())
  766. {
  767. Debug.InventoryMoveLog("Juncture sended", "SYNC_MOVE" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  768. }
  769. #endif
  770. if (!GameInventory.LocationCanMoveEntity(src, dst))
  771. {
  772. #ifdef ENABLE_LOGGING
  773. #ifdef DEVELOPER
  774. DumpInventoryDebug();
  775. #endif
  776. if (LogManager.IsInventoryMoveLogEnable())
  777. {
  778. Debug.InventoryMoveLog("Failed - LocationCanMoveEntity - Juncture denied", "SYNC_MOVE" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  779. }
  780. #endif
  781. validation.m_Result = InventoryValidationResult.FAILED;
  782. return true;
  783. }
  784. validation.m_Result = InventoryValidationResult.JUNCTURE;
  785. EnableMovableOverride(src.GetItem());
  786. return true;
  787. }
  788. else
  789. {
  790. #ifdef ENABLE_LOGGING
  791. if ( LogManager.IsInventoryMoveLogEnable() )
  792. {
  793. Debug.InventoryMoveLog("Juncture denied", "SYNC_MOVE" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  794. }
  795. #endif
  796. validation.m_Result = InventoryValidationResult.FAILED;
  797. validation.m_Reason = InventoryValidationReason.JUNCTURE_DENIED;
  798. return true;
  799. }
  800. }
  801. if (GetDayZPlayerOwner().GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_CLIENT)
  802. {
  803. ClearInventoryReservationEx(dst.GetItem(), dst);
  804. }
  805. //! Is called twice unfortunately...
  806. if (GetDayZPlayerOwner().GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER)
  807. {
  808. CheckForRope(src, dst);
  809. }
  810. //! Do not check for action validity on remotes or when performing through juncture.
  811. //! Juncture locks guarentee the item is safe to interact with and the server has validated the command at this point.
  812. //! Checking at this point is both wasteful and can result in a failure which leads to desync
  813. if (!validation.m_IsRemote && !validation.m_IsJuncture && !GameInventory.LocationCanMoveEntitySyncCheck(src, dst))
  814. {
  815. #ifdef ENABLE_LOGGING
  816. #ifdef DEVELOPER
  817. DumpInventoryDebug();
  818. #endif
  819. if (LogManager.IsInventoryMoveLogEnable())
  820. {
  821. Debug.InventoryMoveLog("Failed - LocationCanMoveEntity", "SYNC_MOVE" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  822. }
  823. #endif
  824. Error("[desync] HandleInputData man=" + Object.GetDebugName(GetManOwner()) + " CANNOT move cmd=" + typename.EnumToString(InventoryCommandType, type) + " src=" + InventoryLocation.DumpToStringNullSafe(src) + " dst=" + InventoryLocation.DumpToStringNullSafe(dst));
  825. return true;
  826. }
  827. #ifdef ENABLE_LOGGING
  828. if (LogManager.IsInventoryMoveLogEnable())
  829. {
  830. Debug.InventoryMoveLog("Success - LocationSyncMoveEntity", "SYNC_MOVE" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  831. }
  832. #endif
  833. LocationSyncMoveEntity(src, dst);
  834. validation.m_Result = InventoryValidationResult.SUCCESS;
  835. return true;
  836. }
  837. bool ValidateHandEvent(inout Serializer ctx, InventoryValidation validation)
  838. {
  839. InventoryCommandType type = InventoryCommandType.HAND_EVENT;
  840. bool success = true;
  841. HandEventBase e = HandEventBase.CreateHandEventFromContext(ctx);
  842. e.ClearInventoryReservation();
  843. //! Pass partial information to guards so guards can do minimal checks if needed
  844. //! The guards can't prevent event so it would be incorrect to pass full InventoryValidation struct.
  845. //! 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)
  846. e.m_IsRemote = validation.m_IsRemote;
  847. e.m_IsJuncture = validation.m_IsJuncture;
  848. EntityAI itemSrc = e.GetSrcEntity();
  849. EntityAI itemDst = e.GetSecondSrcEntity();
  850. #ifdef ENABLE_LOGGING
  851. if (LogManager.IsInventoryMoveLogEnable())
  852. {
  853. Debug.InventoryMoveLog("STS = " + e.m_Player.GetSimulationTimeStamp() + " event= " + e.DumpToString(), "HAND_EVENT" , "n/a", "ProcessInputData", e.m_Player.ToString() );
  854. }
  855. #endif
  856. if (validation.m_IsRemote && !e.GetSrcEntity())
  857. {
  858. //! kumarjac: This indicates a failure in replication relationships as player full inventory should be synchronized always if player exists on the remote
  859. #ifdef ENABLE_LOGGING
  860. if (LogManager.IsInventoryMoveLogEnable())
  861. {
  862. Debug.InventoryMoveLog("Failed - CheckRequestSrc", "HAND_EVENT" , "n/a", "ProcessInputData", e.m_Player.ToString() );
  863. }
  864. #endif
  865. Error("[syncinv] HandleInputData remote input (cmd=HAND_EVENT, event=" + e.DumpToString() + ") dropped, item not in bubble");
  866. return true;
  867. }
  868. //! TODO(kumarjac): Is this one correct to be 'RemoveMovableOverride' or are the other Validate methdos wrong with 'EnableMovableOverride'?
  869. if (itemSrc)
  870. RemoveMovableOverride(itemSrc);
  871. if (itemDst)
  872. RemoveMovableOverride(itemDst);
  873. //! Do not check for action validity on remotes or when performing through juncture.
  874. //! Juncture locks guarentee the item is safe to interact with and the server has validated the command at this point.
  875. //! Checking at this point is both wasteful and can result in a failure which leads to desync
  876. if (success && !validation.m_IsRemote && !validation.m_IsJuncture && !e.CheckRequestSrc())
  877. {
  878. #ifdef ENABLE_LOGGING
  879. if (LogManager.IsInventoryMoveLogEnable())
  880. {
  881. Debug.InventoryMoveLog("Failed - CheckRequestSrc", "HAND_EVENT" , "n/a", "ProcessInputData", e.m_Player.ToString() );
  882. }
  883. #endif
  884. if (!validation.m_IsRemote)
  885. {
  886. ctx = new ScriptInputUserData;
  887. InventoryInputUserData.SerializeHandEvent(ctx, e);
  888. }
  889. RemoveMovableOverride(itemSrc);
  890. RemoveMovableOverride(itemDst);
  891. if (GetDayZPlayerOwner().GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER)
  892. {
  893. success = false;
  894. }
  895. else
  896. {
  897. return true;
  898. }
  899. }
  900. if (success && !e.CheckRequestEx(validation))
  901. {
  902. #ifdef ENABLE_LOGGING
  903. if (LogManager.IsInventoryMoveLogEnable())
  904. {
  905. Debug.InventoryMoveLog("Failed - CheckRequest", "HAND_EVENT" , "n/a", "ProcessInputData", e.m_Player.ToString() );
  906. }
  907. #endif
  908. //! 'HandEventBase.CheckRequestEx' updates failure reason
  909. ctx = new ScriptInputUserData;
  910. InventoryInputUserData.SerializeHandEvent(ctx, e);
  911. #ifdef ENABLE_LOGGING
  912. if (LogManager.IsSyncLogEnable())
  913. {
  914. syncDebugPrint("[cheat] HandleInputData man=" + Object.GetDebugName(GetManOwner()) + " STS = " + GetDayZPlayerOwner().GetSimulationTimeStamp() + " is cheating with cmd=" + typename.EnumToString(InventoryCommandType, type) + " event=" + e.DumpToString());
  915. }
  916. #endif
  917. RemoveMovableOverride(itemSrc);
  918. RemoveMovableOverride(itemDst);
  919. if (GetDayZPlayerOwner().GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER)
  920. {
  921. success = false;
  922. }
  923. else
  924. {
  925. return true;
  926. }
  927. }
  928. //! if it already happened on server, remote just needs to comply
  929. //! TODO(kumarjac): Move m_IsRemote check to inside of HandEventBase.CanPerformEventEx
  930. if (success && !validation.m_IsRemote && !e.CanPerformEventEx(validation))
  931. {
  932. #ifdef ENABLE_LOGGING
  933. if (LogManager.IsInventoryMoveLogEnable())
  934. {
  935. Debug.InventoryMoveLog("Failed - CanPerformEvent", "HAND_EVENT" , "n/a", "ProcessInputData", e.m_Player.ToString() );
  936. }
  937. #endif
  938. //! 'HandEventBase.CanPerformEventEx' updates failure reason
  939. ctx = new ScriptInputUserData;
  940. InventoryInputUserData.SerializeHandEvent(ctx, e);
  941. #ifdef ENABLE_LOGGING
  942. if (LogManager.IsSyncLogEnable())
  943. {
  944. syncDebugPrint("[desync] HandleInputData man=" + Object.GetDebugName(GetManOwner()) + " CANNOT do cmd=HAND_EVENT e=" + e.DumpToString());
  945. }
  946. #endif
  947. RemoveMovableOverride(itemSrc);
  948. RemoveMovableOverride(itemDst);
  949. if (GetDayZPlayerOwner().GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER)
  950. {
  951. success = false;
  952. }
  953. else
  954. {
  955. return true;
  956. }
  957. }
  958. RemoveMovableOverride(itemSrc);
  959. RemoveMovableOverride(itemDst);
  960. //! Check if this this is being executed on the server and not by a juncture or AI
  961. if (!validation.m_IsJuncture && GetDayZPlayerOwner().GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER)
  962. {
  963. JunctureRequestResult result_ev = e.AcquireInventoryJunctureFromServer(GetDayZPlayerOwner());
  964. if (result_ev == JunctureRequestResult.JUNCTURE_NOT_REQUIRED)
  965. {
  966. #ifdef ENABLE_LOGGING
  967. if (LogManager.IsInventoryMoveLogEnable())
  968. {
  969. Debug.InventoryMoveLog("Juncture not required", "HAND_EVENT" , "n/a", "ProcessInputData", e.m_Player.ToString() );
  970. }
  971. #endif
  972. //! Continuing on with execution of rest of the function
  973. }
  974. else if (success && result_ev == JunctureRequestResult.JUNCTURE_ACQUIRED)
  975. {
  976. #ifdef ENABLE_LOGGING
  977. if (LogManager.IsInventoryMoveLogEnable())
  978. {
  979. Debug.InventoryMoveLog("Juncture sended", "HAND_EVENT" , "n/a", "ProcessInputData", e.m_Player.ToString() );
  980. }
  981. #endif
  982. ctx = new ScriptInputUserData;
  983. InventoryInputUserData.SerializeHandEvent(ctx, e);
  984. validation.m_Result = InventoryValidationResult.JUNCTURE;
  985. if (itemSrc)
  986. EnableMovableOverride(itemSrc);
  987. if (itemDst)
  988. EnableMovableOverride(itemDst);
  989. return true;
  990. }
  991. else
  992. {
  993. #ifdef ENABLE_LOGGING
  994. if (LogManager.IsInventoryMoveLogEnable())
  995. {
  996. Debug.InventoryMoveLog("Juncture denied", "HAND_EVENT" , "n/a", "ProcessInputData", e.m_Player.ToString() );
  997. }
  998. #endif
  999. validation.m_Reason = InventoryValidationReason.JUNCTURE_DENIED;
  1000. return true;
  1001. }
  1002. }
  1003. //! Is called twice unfortunately... but it works so won't change
  1004. if (success && GetDayZPlayerOwner().GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER)
  1005. {
  1006. CheckForRope(e.GetSrc(), e.GetDst());
  1007. }
  1008. #ifdef ENABLE_LOGGING
  1009. if (LogManager.IsInventoryMoveLogEnable())
  1010. {
  1011. Debug.InventoryMoveLog("Success - ProcessHandEvent", "HAND_EVENT" , "n/a", "ProcessInputData", e.m_Player.ToString() );
  1012. }
  1013. #endif
  1014. if (success)
  1015. {
  1016. validation.m_Result = InventoryValidationResult.SUCCESS;
  1017. if (!e.m_Player.GetHumanInventory().ProcessHandEvent(e))
  1018. {
  1019. //! TODO(kumarjac): We should probably set the result to failure like so
  1020. //result = InventoryValidationResult.FAILURE;
  1021. }
  1022. }
  1023. return true;
  1024. }
  1025. bool ValidateSwap(inout Serializer ctx, InventoryValidation validation)
  1026. {
  1027. InventoryCommandType type = InventoryCommandType.SWAP;
  1028. InventoryLocation src1 = new InventoryLocation;
  1029. InventoryLocation src2 = new InventoryLocation;
  1030. InventoryLocation dst1 = new InventoryLocation;
  1031. InventoryLocation dst2 = new InventoryLocation;
  1032. bool skippedSwap = false;
  1033. bool success = true;
  1034. src1.ReadFromContext(ctx);
  1035. src2.ReadFromContext(ctx);
  1036. dst1.ReadFromContext(ctx);
  1037. dst2.ReadFromContext(ctx);
  1038. ctx.Read(skippedSwap);
  1039. #ifdef ENABLE_LOGGING
  1040. if (LogManager.IsInventoryMoveLogEnable())
  1041. {
  1042. 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() );
  1043. }
  1044. #endif
  1045. if (validation.m_IsRemote && (!src1.GetItem() || !src2.GetItem()))
  1046. {
  1047. if (skippedSwap)
  1048. {
  1049. #ifdef ENABLE_LOGGING
  1050. if (LogManager.IsInventoryMoveLogEnable())
  1051. {
  1052. Debug.InventoryMoveLog("Remote - skipped", "SWAP" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  1053. }
  1054. #endif
  1055. /*
  1056. if (LogManager.IsSyncLogEnable())
  1057. {
  1058. syncDebugPrint("[syncinv] HandleInputData remote input (cmd=SWAP) dropped, swap is skipped");
  1059. }
  1060. */
  1061. }
  1062. else
  1063. {
  1064. //! kumarjac: This indicates a failure in replication relationships as player full inventory should be synchronized always if player exists on the remote
  1065. #ifdef ENABLE_LOGGING
  1066. if (LogManager.IsInventoryMoveLogEnable())
  1067. {
  1068. Debug.InventoryMoveLog("Failed - item1 or item2 not exist", "SWAP" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  1069. }
  1070. #endif
  1071. Error("[syncinv] HandleInputData remote input (cmd=SWAP) dropped, item not in bubble");
  1072. }
  1073. return true;
  1074. }
  1075. EnableMovableOverride(src1.GetItem());
  1076. EnableMovableOverride(src2.GetItem());
  1077. //! Do not check for action validity on remotes or when performing through juncture.
  1078. //! Juncture locks guarentee the item is safe to interact with and the server has validated the command at this point.
  1079. //! Checking at this point is both wasteful and can result in a failure which leads to desync
  1080. if (success && !validation.m_IsRemote && !validation.m_IsJuncture && !PlayerCheckRequestSrc(src1, GameInventory.c_MaxItemDistanceRadius))
  1081. {
  1082. #ifdef ENABLE_LOGGING
  1083. if (LogManager.IsInventoryMoveLogEnable())
  1084. {
  1085. Debug.InventoryMoveLog("Failed - CheckRequestSrc1", "SWAP" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  1086. }
  1087. if (LogManager.IsSyncLogEnable())
  1088. {
  1089. syncDebugPrint("[cheat] HandleInputData man=" + Object.GetDebugName(GetManOwner()) + " failed src1 check with cmd=" + typename.EnumToString(InventoryCommandType, type) + " src1=" + InventoryLocation.DumpToStringNullSafe(src1));
  1090. }
  1091. #endif
  1092. RemoveMovableOverride(src1.GetItem());
  1093. RemoveMovableOverride(src2.GetItem());
  1094. if (GetDayZPlayerOwner().GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER)
  1095. {
  1096. success = false;
  1097. }
  1098. else
  1099. {
  1100. return true;
  1101. }
  1102. }
  1103. //! Do not check for action validity on remotes or when performing through juncture.
  1104. //! Juncture locks guarentee the item is safe to interact with and the server has validated the command at this point.
  1105. //! Checking at this point is both wasteful and can result in a failure which leads to desync
  1106. if (success && !validation.m_IsRemote && !validation.m_IsJuncture && !PlayerCheckRequestSrc(src2, GameInventory.c_MaxItemDistanceRadius))
  1107. {
  1108. #ifdef ENABLE_LOGGING
  1109. if (LogManager.IsInventoryMoveLogEnable())
  1110. {
  1111. Debug.InventoryMoveLog("Failed - CheckRequestSrc2", "SWAP" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  1112. }
  1113. if (LogManager.IsSyncLogEnable())
  1114. {
  1115. syncDebugPrint("[cheat] HandleInputData man=" + Object.GetDebugName(GetManOwner()) + " failed src2 check with cmd=" + typename.EnumToString(InventoryCommandType, type) + " src2=" + InventoryLocation.DumpToStringNullSafe(src2));
  1116. }
  1117. #endif
  1118. RemoveMovableOverride(src1.GetItem());
  1119. RemoveMovableOverride(src2.GetItem());
  1120. if (GetDayZPlayerOwner().GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER)
  1121. {
  1122. success = false;
  1123. }
  1124. else
  1125. {
  1126. return true;
  1127. }
  1128. }
  1129. //! Do not check for action validity on remotes or when performing through juncture.
  1130. //! Juncture locks guarentee the item is safe to interact with and the server has validated the command at this point.
  1131. //! Checking at this point is both wasteful and can result in a failure which leads to desync
  1132. if (success && !validation.m_IsRemote && !validation.m_IsJuncture && !PlayerCheckSwapItemsRequest(src1, src2, dst1, dst2, GameInventory.c_MaxItemDistanceRadius))
  1133. {
  1134. #ifdef ENABLE_LOGGING
  1135. if (LogManager.IsInventoryMoveLogEnable())
  1136. {
  1137. Debug.InventoryMoveLog("Failed - CheckSwapItemsRequest", "SWAP" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  1138. }
  1139. if (LogManager.IsSyncLogEnable())
  1140. {
  1141. 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));
  1142. }
  1143. #endif
  1144. RemoveMovableOverride(src1.GetItem());
  1145. RemoveMovableOverride(src2.GetItem());
  1146. if (GetDayZPlayerOwner().GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER)
  1147. {
  1148. success = false;
  1149. }
  1150. else
  1151. {
  1152. return true;
  1153. }
  1154. }
  1155. RemoveMovableOverride(src1.GetItem());
  1156. RemoveMovableOverride(src2.GetItem());
  1157. if (GetDayZPlayerOwner().GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_CLIENT)
  1158. {
  1159. ClearInventoryReservationEx(dst1.GetItem(), dst1);
  1160. ClearInventoryReservationEx(dst2.GetItem(), dst2);
  1161. }
  1162. //! Do not check for action validity on remotes or when performing through juncture.
  1163. //! Juncture locks guarentee the item is safe to interact with and the server has validated the command at this point.
  1164. //! Checking at this point is both wasteful and can result in a failure which leads to desync
  1165. if (success && !validation.m_IsRemote && !validation.m_IsJuncture && !GameInventory.CanForceSwapEntitiesEx(src1.GetItem(), dst1, src2.GetItem(), dst2))
  1166. {
  1167. #ifdef ENABLE_LOGGING
  1168. #ifdef DEVELOPER
  1169. DumpInventoryDebug();
  1170. #endif
  1171. if (LogManager.IsInventoryMoveLogEnable())
  1172. {
  1173. Debug.InventoryMoveLog("Failed - CanForceSwapEntitiesEx", "SWAP" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  1174. }
  1175. #endif
  1176. if (GetDayZPlayerOwner().GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER)
  1177. {
  1178. success = false;
  1179. }
  1180. else
  1181. {
  1182. 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));
  1183. return true;
  1184. }
  1185. }
  1186. if (GetDayZPlayerOwner().GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_CLIENT)
  1187. {
  1188. AddInventoryReservationEx(dst1.GetItem(), dst1, GameInventory.c_InventoryReservationTimeoutShortMS);
  1189. AddInventoryReservationEx(dst2.GetItem(), dst2, GameInventory.c_InventoryReservationTimeoutShortMS);
  1190. }
  1191. if (!(src1.IsValid() && src2.IsValid() && dst1.IsValid() && dst2.IsValid()))
  1192. {
  1193. 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));
  1194. return true;
  1195. }
  1196. //! Check if this this is being executed on the server and not by a juncture or AI
  1197. if (!validation.m_IsJuncture && GetDayZPlayerOwner().GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER)
  1198. {
  1199. JunctureRequestResult result_sw = TryAcquireTwoInventoryJuncturesFromServer(GetDayZPlayerOwner(), src1, src2, dst1, dst2);
  1200. if (result_sw == JunctureRequestResult.JUNCTURE_NOT_REQUIRED)
  1201. {
  1202. #ifdef ENABLE_LOGGING
  1203. if (LogManager.IsInventoryMoveLogEnable())
  1204. {
  1205. Debug.InventoryMoveLog("Juncture not required", "SWAP" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  1206. }
  1207. #endif
  1208. //! Continuing on with execution of rest of the function
  1209. }
  1210. else if (success && result_sw == JunctureRequestResult.JUNCTURE_ACQUIRED)
  1211. {
  1212. #ifdef ENABLE_LOGGING
  1213. if (LogManager.IsInventoryMoveLogEnable())
  1214. {
  1215. Debug.InventoryMoveLog("Juncture sended", "SWAP" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  1216. }
  1217. #endif
  1218. validation.m_Result = InventoryValidationResult.JUNCTURE;
  1219. EnableMovableOverride(src1.GetItem());
  1220. EnableMovableOverride(src2.GetItem());
  1221. return true;
  1222. }
  1223. else
  1224. {
  1225. #ifdef ENABLE_LOGGING
  1226. if (LogManager.IsInventoryMoveLogEnable())
  1227. {
  1228. Debug.InventoryMoveLog("Juncture denied", "SWAP" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  1229. }
  1230. #endif
  1231. validation.m_Result = InventoryValidationResult.FAILED;
  1232. validation.m_Reason = InventoryValidationReason.JUNCTURE_DENIED;
  1233. return true;
  1234. }
  1235. }
  1236. if (GetDayZPlayerOwner().GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_CLIENT )
  1237. {
  1238. ClearInventoryReservationEx(dst1.GetItem(),dst1);
  1239. ClearInventoryReservationEx(dst2.GetItem(),dst2);
  1240. }
  1241. #ifdef ENABLE_LOGGING
  1242. if (LogManager.IsInventoryMoveLogEnable())
  1243. {
  1244. Debug.InventoryMoveLog("Success - item swap", "SWAP" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  1245. }
  1246. #endif
  1247. if (success)
  1248. {
  1249. bool isNotSkipped = LocationSwap(src1, src2, dst1, dst2);
  1250. ctx = new ScriptInputUserData();
  1251. InventoryInputUserData.SerializeSwap(ctx, src1, src2, dst1, dst2, !isNotSkipped);
  1252. validation.m_Result = InventoryValidationResult.SUCCESS;
  1253. }
  1254. return true;
  1255. }
  1256. bool ValidateDestroy(inout Serializer ctx, InventoryValidation validation)
  1257. {
  1258. InventoryCommandType type = InventoryCommandType.DESTROY;
  1259. if (validation.m_IsJuncture)
  1260. {
  1261. /** TODO(kumarjac):
  1262. * Probably should be called through inventory juncture,
  1263. * we shouldn't allow the client to delete until the
  1264. * server says it is okay as there can be more reasons
  1265. * than "cheater" for it to be rejected such as desync
  1266. */
  1267. return true;
  1268. }
  1269. InventoryLocation src = new InventoryLocation;
  1270. src.ReadFromContext(ctx);
  1271. #ifdef ENABLE_LOGGING
  1272. if (LogManager.IsInventoryMoveLogEnable())
  1273. {
  1274. Debug.InventoryMoveLog("STS = " + GetDayZPlayerOwner().GetSimulationTimeStamp() + " src=" + InventoryLocation.DumpToStringNullSafe(src), "DESTROY" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  1275. }
  1276. #endif
  1277. if (validation.m_IsRemote && !src.GetItem())
  1278. {
  1279. #ifdef ENABLE_LOGGING
  1280. if (LogManager.IsInventoryMoveLogEnable())
  1281. {
  1282. Debug.InventoryMoveLog("Failed item not exist", "DESTROY" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  1283. }
  1284. #endif
  1285. Error("[syncinv] HandleInputData remote input (cmd=DESTROY) dropped, item not in bubble");
  1286. return true;
  1287. }
  1288. //! Do not check for action validity on remotes or when performing through juncture.
  1289. //! Juncture locks guarentee the item is safe to interact with and the server has validated the command at this point.
  1290. //! Checking at this point is both wasteful and can result in a failure which leads to desync
  1291. if (!validation.m_IsRemote && !validation.m_IsJuncture && !PlayerCheckRequestSrc(src, GameInventory.c_MaxItemDistanceRadius))
  1292. {
  1293. #ifdef ENABLE_LOGGING
  1294. if (LogManager.IsInventoryMoveLogEnable())
  1295. {
  1296. Debug.InventoryMoveLog("Failed CheckRequestSrc", "DESTROY" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  1297. }
  1298. #endif
  1299. return true;
  1300. }
  1301. //! Do not check for action validity on remotes or when performing through juncture.
  1302. //! Juncture locks guarentee the item is safe to interact with and the server has validated the command at this point.
  1303. //! Checking at this point is both wasteful and can result in a failure which leads to desync
  1304. if (!validation.m_IsRemote && !validation.m_IsJuncture && !PlayerCheckDropRequest(src, GameInventory.c_MaxItemDistanceRadius))
  1305. {
  1306. #ifdef ENABLE_LOGGING
  1307. if (LogManager.IsInventoryMoveLogEnable())
  1308. {
  1309. Debug.InventoryMoveLog("Failed CheckDropRequest", "DESTROY" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  1310. }
  1311. #endif
  1312. return true;
  1313. }
  1314. #ifdef ENABLE_LOGGING
  1315. if (LogManager.IsInventoryMoveLogEnable())
  1316. {
  1317. Debug.InventoryMoveLog("Success ObjectDelete", "DESTROY" , "n/a", "ProcessInputData", GetDayZPlayerOwner().ToString() );
  1318. }
  1319. #endif
  1320. GetGame().ObjectDelete(src.GetItem());
  1321. validation.m_Result = InventoryValidationResult.SUCCESS;
  1322. return true;
  1323. }
  1324. /**
  1325. *
  1326. * @return false on malformed data, true on anything else, including cheats
  1327. */
  1328. bool ProcessInputData(ParamsReadContext ctx, bool isJuncture, bool isRemote)
  1329. {
  1330. if (isJuncture && isRemote)
  1331. {
  1332. //! It should be impossible for juncture to be ran on remote
  1333. return false;
  1334. }
  1335. int type = -1;
  1336. if (!ctx.Read(type))
  1337. {
  1338. return false;
  1339. }
  1340. InventoryValidation validation();
  1341. validation.m_IsJuncture = isJuncture;
  1342. validation.m_IsRemote = isRemote;
  1343. //! Serializer can be updated and re-written to when we may want to only correct the client instead of denying the inventory command
  1344. Serializer serializer = ctx;
  1345. switch (type)
  1346. {
  1347. case InventoryCommandType.USER_RESERVATION_CANCEL:
  1348. if (!ValidateUserReservationCancel(serializer, validation))
  1349. {
  1350. return false;
  1351. }
  1352. break;
  1353. case InventoryCommandType.SYNC_MOVE:
  1354. if (!ValidateSyncMove(serializer, validation))
  1355. {
  1356. return false;
  1357. }
  1358. break;
  1359. case InventoryCommandType.HAND_EVENT:
  1360. if (!ValidateHandEvent(serializer, validation))
  1361. {
  1362. return false;
  1363. }
  1364. break;
  1365. case InventoryCommandType.SWAP:
  1366. if (!ValidateSwap(serializer, validation))
  1367. {
  1368. return false;
  1369. }
  1370. break;
  1371. case InventoryCommandType.DESTROY:
  1372. if (!ValidateDestroy(serializer, validation))
  1373. {
  1374. return false;
  1375. }
  1376. break;
  1377. default:
  1378. break;
  1379. }
  1380. bool canSendJuncture = !isJuncture && GetDayZPlayerOwner().GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER;
  1381. switch (validation.m_Result)
  1382. {
  1383. case InventoryValidationResult.FAILED:
  1384. if (canSendJuncture) //! Only inform client about failure
  1385. {
  1386. //! General purpose serializer change from read to write here if the validation doesn't update it
  1387. if (!serializer.CanWrite())
  1388. {
  1389. ScriptInputUserData writeableSerializer();
  1390. writeableSerializer.CopyFrom(serializer);
  1391. serializer = writeableSerializer;
  1392. }
  1393. serializer.Write(validation.m_Reason);
  1394. GetDayZPlayerOwner().SendSyncJuncture(DayZPlayerSyncJunctures.SJ_INVENTORY_FAILURE, serializer);
  1395. }
  1396. break;
  1397. case InventoryValidationResult.JUNCTURE:
  1398. if (canSendJuncture) //! Only send juncture back to client
  1399. {
  1400. GetDayZPlayerOwner().SendSyncJuncture(DayZPlayerSyncJunctures.SJ_INVENTORY, serializer);
  1401. //StoreInputForRemotes(isJuncture, isRemote, serializer);
  1402. }
  1403. else
  1404. {
  1405. Error("InventoryValidationResult.JUNCTURE returned when not possible to send!");
  1406. }
  1407. break;
  1408. case InventoryValidationResult.SUCCESS:
  1409. StoreInputForRemotes(isJuncture, isRemote, serializer);
  1410. break;
  1411. }
  1412. return true;
  1413. }
  1414. void RemoveMovableOverride(EntityAI item)
  1415. {
  1416. ItemBase itemIB = ItemBase.Cast(item);
  1417. if (itemIB)
  1418. itemIB.SetCanBeMovedOverride(false);
  1419. }
  1420. void EnableMovableOverride(EntityAI item)
  1421. {
  1422. ItemBase itemIB = ItemBase.Cast(item);
  1423. if (itemIB)
  1424. itemIB.SetCanBeMovedOverride(true);
  1425. }
  1426. // Hacky solution for dealing with fencekit rope related issues, could be fixed by introducing some indicator that this item behaves differently or sth..
  1427. void CheckForRope(InventoryLocation src, InventoryLocation dst)
  1428. {
  1429. Rope rope = Rope.Cast(src.GetItem());
  1430. if (rope)
  1431. rope.SetTargetLocation(dst);
  1432. }
  1433. bool IsServerOrLocalPlayer()
  1434. {
  1435. return GetDayZPlayerOwner().GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER || GetDayZPlayerOwner() == GetGame().GetPlayer());
  1436. }
  1437. bool StoreInputForRemotes (bool handling_juncture, bool remote, ParamsReadContext ctx)
  1438. {
  1439. if (!remote && GetDayZPlayerOwner().GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER)
  1440. {
  1441. #ifdef ENABLE_LOGGING
  1442. if (LogManager.IsInventoryMoveLogEnable())
  1443. {
  1444. Debug.InventoryMoveLog("STS = " + GetDayZPlayerOwner().GetSimulationTimeStamp(), "n/a" , "n/a", "StoreInputForRemotes", GetDayZPlayerOwner().ToString() );
  1445. }
  1446. #endif
  1447. GetDayZPlayerOwner().StoreInputForRemotes(ctx); // @NOTE: needs to be called _after_ the operation
  1448. return true;
  1449. }
  1450. return false;
  1451. }
  1452. override bool TakeToDst (InventoryMode mode, notnull InventoryLocation src, notnull InventoryLocation dst)
  1453. {
  1454. if (GetManOwner().IsAlive() == false)
  1455. return super.TakeToDst(mode, src, dst);
  1456. #ifdef ENABLE_LOGGING
  1457. if (LogManager.IsInventoryMoveLogEnable())
  1458. {
  1459. Debug.InventoryMoveLog("STS = " + GetDayZPlayerOwner().GetSimulationTimeStamp() + " src=" + InventoryLocation.DumpToStringNullSafe(src) + " dst=" + InventoryLocation.DumpToStringNullSafe(dst), "n/a" , "n/a", "TakeToDst", GetDayZPlayerOwner().ToString() );
  1460. }
  1461. #endif
  1462. switch (mode)
  1463. {
  1464. case InventoryMode.SERVER:
  1465. if (RedirectToHandEvent(mode, src, dst))
  1466. {
  1467. #ifdef ENABLE_LOGGING
  1468. if (LogManager.IsInventoryMoveLogEnable())
  1469. {
  1470. Debug.InventoryMoveLog("RedirectToHandEvent", "n/a" , "n/a", "TakeToDst", GetDayZPlayerOwner().ToString() );
  1471. }
  1472. #endif
  1473. return true;
  1474. }
  1475. if (GetDayZPlayerOwner().NeedInventoryJunctureFromServer(src.GetItem(), src.GetParent(), dst.GetParent()))
  1476. {
  1477. if (GetGame().AddInventoryJunctureEx(GetDayZPlayerOwner(), src.GetItem(), dst, true, GameInventory.c_InventoryReservationTimeoutMS))
  1478. {
  1479. #ifdef ENABLE_LOGGING
  1480. if (LogManager.IsSyncLogEnable())
  1481. {
  1482. syncDebugPrint("[syncinv] " + Object.GetDebugName(GetDayZPlayerOwner()) + " STS = " + GetDayZPlayerOwner().GetSimulationTimeStamp() + " DZPI::Take2Dst(" + typename.EnumToString(InventoryMode, mode) + ") got juncture");
  1483. }
  1484. #endif
  1485. }
  1486. else
  1487. {
  1488. #ifdef ENABLE_LOGGING
  1489. if (LogManager.IsInventoryMoveLogEnable())
  1490. {
  1491. Debug.InventoryMoveLog("Juncture failed", "n/a" , "n/a", "TakeToDst", GetDayZPlayerOwner().ToString() );
  1492. }
  1493. if (LogManager.IsSyncLogEnable())
  1494. {
  1495. syncDebugPrint("[syncinv] " + Object.GetDebugName(GetDayZPlayerOwner()) + " STS = " + GetDayZPlayerOwner().GetSimulationTimeStamp() + " DZPI::Take2Dst(" + typename.EnumToString(InventoryMode, mode) + ") got juncture");
  1496. }
  1497. #endif
  1498. return false;
  1499. }
  1500. }
  1501. ScriptInputUserData ctx = new ScriptInputUserData;
  1502. InventoryInputUserData.SerializeMove(ctx, InventoryCommandType.SYNC_MOVE, src, dst);
  1503. GetDayZPlayerOwner().SendSyncJuncture(DayZPlayerSyncJunctures.SJ_INVENTORY, ctx);
  1504. #ifdef ENABLE_LOGGING
  1505. if (LogManager.IsSyncLogEnable())
  1506. {
  1507. 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));
  1508. }
  1509. #endif
  1510. //! 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
  1511. //GetDayZPlayerOwner().StoreInputForRemotes(ctx); // @TODO: is this right place? maybe in HandleInputData(server=true, ...)
  1512. #ifdef ENABLE_LOGGING
  1513. if ( LogManager.IsInventoryMoveLogEnable() )
  1514. {
  1515. 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() );
  1516. }
  1517. #endif
  1518. return true;
  1519. case InventoryMode.LOCAL:
  1520. LocationSyncMoveEntity(src, dst);
  1521. return true;
  1522. }
  1523. if (!super.TakeToDst(mode,src,dst))
  1524. {
  1525. if (!m_DeferredEvent)
  1526. {
  1527. m_DeferredEvent = new DeferredTakeToDst(mode,src,dst);
  1528. if (m_DeferredEvent.ReserveInventory(this))
  1529. return true;
  1530. }
  1531. m_DeferredEvent = null;
  1532. return false;
  1533. }
  1534. return true;
  1535. }
  1536. void HandleTakeToDst( DeferredEvent deferred_event )
  1537. {
  1538. DeferredTakeToDst deferred_take_to_dst = DeferredTakeToDst.Cast(deferred_event);
  1539. if( deferred_take_to_dst )
  1540. {
  1541. #ifdef ENABLE_LOGGING
  1542. if ( LogManager.IsInventoryHFSMLogEnable() )
  1543. {
  1544. Debug.InventoryHFSMLog("STS = " + GetDayZPlayerOwner().GetSimulationTimeStamp(), "n/a" , "n/a", "HandleTakeToDst", GetDayZPlayerOwner().ToString() );
  1545. }
  1546. #endif
  1547. deferred_take_to_dst.ClearInventoryReservation(this);
  1548. if (LogManager.IsInventoryMoveLogEnable())
  1549. {
  1550. 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));
  1551. }
  1552. switch (deferred_take_to_dst.m_mode)
  1553. {
  1554. case InventoryMode.PREDICTIVE:
  1555. #ifdef ENABLE_LOGGING
  1556. if (LogManager.IsInventoryHFSMLogEnable())
  1557. {
  1558. Debug.InventoryHFSMLog("PREDICTIVE ", "n/a" , "n/a", "HandleTakeToDst", GetDayZPlayerOwner().ToString() );
  1559. }
  1560. #endif
  1561. if (LocationCanMoveEntity(deferred_take_to_dst.m_src,deferred_take_to_dst.m_dst))
  1562. {
  1563. InventoryInputUserData.SendInputUserDataMove(InventoryCommandType.SYNC_MOVE, deferred_take_to_dst.m_src, deferred_take_to_dst.m_dst);
  1564. LocationSyncMoveEntity(deferred_take_to_dst.m_src, deferred_take_to_dst.m_dst);
  1565. }
  1566. else
  1567. {
  1568. #ifdef ENABLE_LOGGING
  1569. if (LogManager.IsInventoryMoveLogEnable())
  1570. {
  1571. 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() );
  1572. }
  1573. #endif
  1574. }
  1575. break;
  1576. case InventoryMode.JUNCTURE:
  1577. #ifdef ENABLE_LOGGING
  1578. if (LogManager.IsInventoryHFSMLogEnable())
  1579. {
  1580. Debug.InventoryHFSMLog("JUNCTURE ", "n/a" , "n/a", "HandleTakeToDst", GetDayZPlayerOwner().ToString());
  1581. }
  1582. #endif
  1583. if (LocationCanMoveEntity(deferred_take_to_dst.m_src,deferred_take_to_dst.m_dst))
  1584. {
  1585. DayZPlayer player = GetGame().GetPlayer();
  1586. player.GetHumanInventory().AddInventoryReservationEx(deferred_take_to_dst.m_dst.GetItem(), deferred_take_to_dst.m_dst, GameInventory.c_InventoryReservationTimeoutShortMS);
  1587. EnableMovableOverride(deferred_take_to_dst.m_dst.GetItem());
  1588. InventoryInputUserData.SendInputUserDataMove(InventoryCommandType.SYNC_MOVE, deferred_take_to_dst.m_src, deferred_take_to_dst.m_dst);
  1589. }
  1590. else
  1591. {
  1592. #ifdef ENABLE_LOGGING
  1593. if (LogManager.IsInventoryMoveLogEnable())
  1594. {
  1595. 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());
  1596. }
  1597. #endif
  1598. }
  1599. break;
  1600. case InventoryMode.LOCAL:
  1601. #ifdef ENABLE_LOGGING
  1602. if (LogManager.IsInventoryHFSMLogEnable())
  1603. {
  1604. Debug.InventoryHFSMLog("LOCAL ", "n/a" , "n/a", "HandleTakeToDst", GetDayZPlayerOwner().ToString());
  1605. }
  1606. #endif
  1607. break;
  1608. case InventoryMode.SERVER:
  1609. #ifdef ENABLE_LOGGING
  1610. if (LogManager.IsInventoryHFSMLogEnable())
  1611. {
  1612. Debug.InventoryHFSMLog("SERVER ", "n/a" , "n/a", "HandleTakeToDst", GetDayZPlayerOwner().ToString());
  1613. }
  1614. #endif
  1615. break;
  1616. default:
  1617. Error("HandEvent - Invalid mode");
  1618. break;
  1619. }
  1620. }
  1621. }
  1622. override bool SwapEntities (InventoryMode mode, notnull EntityAI item1, notnull EntityAI item2)
  1623. {
  1624. #ifdef ENABLE_LOGGING
  1625. if (LogManager.IsInventoryMoveLogEnable())
  1626. {
  1627. Debug.InventoryMoveLog("STS = " + GetDayZPlayerOwner().GetSimulationTimeStamp() + " item1 = " + item1 + " item2 = " + item2, "n/a" , "n/a", "SwapEntities", GetDayZPlayerOwner().ToString() );
  1628. }
  1629. #endif
  1630. InventoryLocation src1, src2, dst1, dst2;
  1631. if( mode == InventoryMode.LOCAL )
  1632. {
  1633. if (GameInventory.MakeSrcAndDstForSwap(item1, item2, src1, src2, dst1, dst2))
  1634. {
  1635. LocationSwap(src1, src2, dst1, dst2);
  1636. return true;
  1637. }
  1638. }
  1639. if(!super.SwapEntities(mode,item1,item2))
  1640. {
  1641. if(!m_DeferredEvent)
  1642. {
  1643. if( GameInventory.MakeSrcAndDstForSwap(item1, item2, src1, src2, dst1, dst2) );
  1644. {
  1645. m_DeferredEvent = new DeferredSwapEntities(mode, item1, item2, dst1, dst2);
  1646. if( m_DeferredEvent.ReserveInventory(this) )
  1647. return true;
  1648. }
  1649. }
  1650. m_DeferredEvent = null;
  1651. return false;
  1652. }
  1653. return true;
  1654. }
  1655. void HandleSwapEntities( DeferredEvent deferred_event )
  1656. {
  1657. DeferredSwapEntities deferred_swap_entities = DeferredSwapEntities.Cast(deferred_event);
  1658. if( deferred_swap_entities )
  1659. {
  1660. deferred_swap_entities.ClearInventoryReservation(this);
  1661. InventoryLocation src1, src2, dst1, dst2;
  1662. if (GameInventory.MakeSrcAndDstForSwap(deferred_swap_entities.m_item1, deferred_swap_entities.m_item2, src1, src2, dst1, dst2))
  1663. {
  1664. if (LogManager.IsInventoryMoveLogEnable())
  1665. {
  1666. 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));
  1667. }
  1668. switch (deferred_swap_entities.m_mode)
  1669. {
  1670. case InventoryMode.PREDICTIVE:
  1671. if (CanSwapEntitiesEx(deferred_swap_entities.m_dst1.GetItem(),deferred_swap_entities.m_dst2.GetItem()) )
  1672. {
  1673. InventoryInputUserData.SendInputUserDataSwap(src1, src2, deferred_swap_entities.m_dst1, deferred_swap_entities.m_dst2);
  1674. LocationSwap(src1, src2, deferred_swap_entities.m_dst1, deferred_swap_entities.m_dst2);
  1675. }
  1676. else
  1677. {
  1678. #ifdef ENABLE_LOGGING
  1679. if (LogManager.IsInventoryMoveLogEnable())
  1680. {
  1681. 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() );
  1682. }
  1683. #endif
  1684. }
  1685. break;
  1686. case InventoryMode.JUNCTURE:
  1687. if (CanSwapEntitiesEx(deferred_swap_entities.m_dst1.GetItem(),deferred_swap_entities.m_dst2.GetItem()) )
  1688. {
  1689. DayZPlayer player = GetGame().GetPlayer();
  1690. player.GetHumanInventory().AddInventoryReservationEx(deferred_swap_entities.m_dst1.GetItem(), deferred_swap_entities.m_dst1, GameInventory.c_InventoryReservationTimeoutShortMS);
  1691. player.GetHumanInventory().AddInventoryReservationEx(deferred_swap_entities.m_dst2.GetItem(), deferred_swap_entities.m_dst2, GameInventory.c_InventoryReservationTimeoutShortMS);
  1692. EnableMovableOverride(deferred_swap_entities.m_dst1.GetItem());
  1693. EnableMovableOverride(deferred_swap_entities.m_dst2.GetItem());
  1694. InventoryInputUserData.SendInputUserDataSwap(src1, src2, deferred_swap_entities.m_dst1, deferred_swap_entities.m_dst2);
  1695. }
  1696. else
  1697. {
  1698. #ifdef ENABLE_LOGGING
  1699. if (LogManager.IsInventoryMoveLogEnable())
  1700. {
  1701. 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() );
  1702. }
  1703. #endif
  1704. }
  1705. break;
  1706. case InventoryMode.LOCAL:
  1707. break;
  1708. default:
  1709. Error("SwapEntities - HandEvent - Invalid mode");
  1710. }
  1711. }
  1712. else
  1713. Error("SwapEntities - MakeSrcAndDstForSwap - no inv loc");
  1714. }
  1715. }
  1716. override bool ForceSwapEntities (InventoryMode mode, notnull EntityAI item1, notnull EntityAI item2, notnull InventoryLocation item2_dst)
  1717. {
  1718. #ifdef ENABLE_LOGGING
  1719. if (LogManager.IsInventoryMoveLogEnable())
  1720. {
  1721. Debug.InventoryMoveLog("STS = " + GetDayZPlayerOwner().GetSimulationTimeStamp() + " item1 = " + item1 + " item2 = " + item2 + " dst=" + InventoryLocation.DumpToStringNullSafe(item2_dst), "n/a" , "n/a", "ForceSwapEntities", GetDayZPlayerOwner().ToString() );
  1722. }
  1723. #endif
  1724. if( mode == InventoryMode.LOCAL )
  1725. {
  1726. InventoryLocation src1, src2, dst1;
  1727. if (GameInventory.MakeSrcAndDstForForceSwap(item1, item2, src1, src2, dst1, item2_dst))
  1728. {
  1729. LocationSwap(src1, src2, dst1, item2_dst);
  1730. return true;
  1731. }
  1732. }
  1733. if(!super.ForceSwapEntities(mode,item1,item2,item2_dst))
  1734. {
  1735. if(!m_DeferredEvent)
  1736. {
  1737. if (GameInventory.MakeSrcAndDstForForceSwap(item1, item2, src1, src2, dst1, item2_dst))
  1738. {
  1739. m_DeferredEvent = new DeferredForceSwapEntities(mode,item1,item2, dst1, item2_dst);
  1740. if( m_DeferredEvent.ReserveInventory(this))
  1741. return true;
  1742. }
  1743. }
  1744. m_DeferredEvent = null;
  1745. return false;
  1746. }
  1747. return true;
  1748. }
  1749. void HandleForceSwapEntities( DeferredEvent deferred_event )
  1750. {
  1751. DeferredForceSwapEntities deferred_force_swap_entities = DeferredForceSwapEntities.Cast(deferred_event);
  1752. if (deferred_force_swap_entities)
  1753. {
  1754. deferred_force_swap_entities.ClearInventoryReservation(this);
  1755. InventoryLocation src1 = new InventoryLocation;
  1756. InventoryLocation src2 = new InventoryLocation;
  1757. deferred_force_swap_entities.m_item1.GetInventory().GetCurrentInventoryLocation(src1);
  1758. deferred_force_swap_entities.m_item2.GetInventory().GetCurrentInventoryLocation(src2);
  1759. DayZPlayer player = GetGame().GetPlayer();
  1760. if (LogManager.IsInventoryMoveLogEnable())
  1761. {
  1762. 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));
  1763. }
  1764. switch (deferred_force_swap_entities.m_mode)
  1765. {
  1766. case InventoryMode.PREDICTIVE:
  1767. 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))
  1768. {
  1769. InventoryInputUserData.SendInputUserDataSwap(src1, src2, deferred_force_swap_entities.m_dst1, deferred_force_swap_entities.m_dst2);
  1770. LocationSwap(src1, src2, deferred_force_swap_entities.m_dst1, deferred_force_swap_entities.m_dst2);
  1771. }
  1772. else
  1773. {
  1774. #ifdef ENABLE_LOGGING
  1775. if (LogManager.IsInventoryMoveLogEnable())
  1776. {
  1777. 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());
  1778. }
  1779. #endif
  1780. }
  1781. break;
  1782. case InventoryMode.JUNCTURE:
  1783. 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))
  1784. {
  1785. player.GetHumanInventory().AddInventoryReservationEx(deferred_force_swap_entities.m_item1, deferred_force_swap_entities.m_dst1, GameInventory.c_InventoryReservationTimeoutShortMS);
  1786. player.GetHumanInventory().AddInventoryReservationEx(deferred_force_swap_entities.m_item2, deferred_force_swap_entities.m_dst2, GameInventory.c_InventoryReservationTimeoutShortMS);
  1787. InventoryInputUserData.SendInputUserDataSwap(src1, src2, deferred_force_swap_entities.m_dst1, deferred_force_swap_entities.m_dst2);
  1788. }
  1789. else
  1790. {
  1791. #ifdef ENABLE_LOGGING
  1792. if (LogManager.IsInventoryMoveLogEnable())
  1793. {
  1794. 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());
  1795. }
  1796. #endif
  1797. }
  1798. break;
  1799. case InventoryMode.LOCAL:
  1800. break;
  1801. default:
  1802. Error("ForceSwapEntities - HandEvent - Invalid mode");
  1803. }
  1804. }
  1805. }
  1806. static void SendServerHandEventViaJuncture (notnull DayZPlayer player, HandEventBase e)
  1807. {
  1808. if (GetGame().IsServer())
  1809. {
  1810. if (e.IsServerSideOnly())
  1811. {
  1812. Error("[syncinv] " + Object.GetDebugName(player) + " SendServerHandEventViaJuncture - called on server side event only, e=" + e.DumpToString());
  1813. }
  1814. if (player.IsAlive())
  1815. {
  1816. InventoryLocation dst = e.GetDst();
  1817. InventoryLocation src = e.GetSrc();
  1818. if (src.IsValid() && dst.IsValid())
  1819. {
  1820. if (player.NeedInventoryJunctureFromServer(src.GetItem(), src.GetParent(), dst.GetParent()))
  1821. {
  1822. #ifdef ENABLE_LOGGING
  1823. if (LogManager.IsSyncLogEnable())
  1824. {
  1825. syncDebugPrint("[syncinv] " + Object.GetDebugName(player) + " STS = " + player.GetSimulationTimeStamp() + " SendServerHandEventViaJuncture(" + typename.EnumToString(InventoryMode, InventoryMode.SERVER) + ") need juncture src=" + InventoryLocation.DumpToStringNullSafe(src) + " dst=" + InventoryLocation.DumpToStringNullSafe(dst));
  1826. }
  1827. #endif
  1828. if (GetGame().AddInventoryJunctureEx(player, src.GetItem(), dst, true, GameInventory.c_InventoryReservationTimeoutMS))
  1829. {
  1830. #ifdef ENABLE_LOGGING
  1831. if (LogManager.IsSyncLogEnable())
  1832. {
  1833. syncDebugPrint("[syncinv] " + Object.GetDebugName(player) + " STS = " + player.GetSimulationTimeStamp() + " SendServerHandEventViaJuncture(" + typename.EnumToString(InventoryMode, InventoryMode.SERVER) + ") got juncture");
  1834. }
  1835. #endif
  1836. }
  1837. else
  1838. {
  1839. #ifdef ENABLE_LOGGING
  1840. if (LogManager.IsSyncLogEnable())
  1841. {
  1842. syncDebugPrint("[syncinv] " + Object.GetDebugName(player) + " STS = " + player.GetSimulationTimeStamp() + " SendServerHandEventViaJuncture(" + typename.EnumToString(InventoryMode, InventoryMode.SERVER) + ") !got juncture");
  1843. }
  1844. #endif
  1845. }
  1846. }
  1847. #ifdef ENABLE_LOGGING
  1848. if (LogManager.IsSyncLogEnable())
  1849. {
  1850. 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));
  1851. }
  1852. #endif
  1853. ScriptInputUserData ctx = new ScriptInputUserData;
  1854. InventoryInputUserData.SerializeHandEvent(ctx, e);
  1855. player.SendSyncJuncture(DayZPlayerSyncJunctures.SJ_INVENTORY, ctx);
  1856. #ifdef ENABLE_LOGGING
  1857. if (LogManager.IsSyncLogEnable())
  1858. {
  1859. 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));
  1860. }
  1861. #endif
  1862. //! 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
  1863. //player.StoreInputForRemotes(ctx); // @TODO: is this right place? maybe in HandleInputData(server=true, ...)
  1864. }
  1865. }
  1866. else
  1867. {
  1868. Error("[syncinv] SendServerHandEventViaJuncture - called on dead player, juncture is for living only");
  1869. }
  1870. }
  1871. }
  1872. /**@fn NetSyncCurrentStateID
  1873. * @brief Engine callback - network synchronization of FSM's state. not intended to direct use.
  1874. **/
  1875. override void NetSyncCurrentStateID (int id)
  1876. {
  1877. super.NetSyncCurrentStateID(id);
  1878. GetDayZPlayerOwner().GetItemAccessor().OnItemInHandsChanged();
  1879. }
  1880. /**@fn OnAfterStoreLoad
  1881. * @brief engine reaction to load from database
  1882. * originates in:
  1883. * engine - Person::BinLoad
  1884. * script - PlayerBase.OnAfterStoreLoad
  1885. **/
  1886. override void OnAfterStoreLoad ()
  1887. {
  1888. GetDayZPlayerOwner().GetItemAccessor().OnItemInHandsChanged(true);
  1889. }
  1890. /**@fn OnEventForRemoteWeapon
  1891. * @brief reaction of remote weapon to (common user/anim/...) event sent from server
  1892. **/
  1893. bool OnEventForRemoteWeapon (ParamsReadContext ctx)
  1894. {
  1895. if (GetEntityInHands())
  1896. {
  1897. Weapon_Base wpn = Weapon_Base.Cast(GetEntityInHands());
  1898. if (wpn)
  1899. {
  1900. PlayerBase pb = PlayerBase.Cast(GetDayZPlayerOwner());
  1901. WeaponEventBase e = CreateWeaponEventFromContext(ctx);
  1902. if (pb && e)
  1903. {
  1904. pb.GetWeaponManager().SetRunning(true);
  1905. if (LogManager.IsWeaponLogEnable())
  1906. {
  1907. fsmDebugSpam("[wpnfsm] " + Object.GetDebugName(wpn) + " recv event from remote: created event=" + e);
  1908. }
  1909. if (e.GetEventID() == WeaponEventID.HUMANCOMMAND_ACTION_ABORTED)
  1910. {
  1911. wpn.ProcessWeaponAbortEvent(e);
  1912. }
  1913. else
  1914. {
  1915. wpn.ProcessWeaponEvent(e);
  1916. }
  1917. pb.GetWeaponManager().SetRunning(false);
  1918. }
  1919. }
  1920. else
  1921. Error("OnEventForRemoteWeapon - entity in hands, but not weapon. item=" + GetEntityInHands());
  1922. }
  1923. else
  1924. Error("OnEventForRemoteWeapon - no entity in hands");
  1925. return true;
  1926. }
  1927. /**@fn OnHandEventForRemote
  1928. * @brief reaction of remote weapon to (common user/anim/...) event sent from server
  1929. **/
  1930. bool OnHandEventForRemote (ParamsReadContext ctx)
  1931. {
  1932. HandEventBase e = HandEventBase.CreateHandEventFromContext(ctx);
  1933. if (e)
  1934. {
  1935. if (LogManager.IsInventoryHFSMLogEnable())
  1936. {
  1937. hndDebugSpam("[hndfsm] recv event from remote: created event=" + e);
  1938. }
  1939. //m_FSM.ProcessEvent(e);
  1940. if (e.GetEventID() == HandEventID.HUMANCOMMAND_ACTION_ABORTED)
  1941. {
  1942. ProcessEventResult aa;
  1943. m_FSM.ProcessAbortEvent(e, aa);
  1944. }
  1945. else
  1946. {
  1947. m_FSM.ProcessEvent(e);
  1948. }
  1949. return true;
  1950. }
  1951. return false;
  1952. }
  1953. void SyncHandEventToRemote (HandEventBase e)
  1954. {
  1955. DayZPlayer p = GetDayZPlayerOwner();
  1956. if (p && p.GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER)
  1957. {
  1958. ScriptRemoteInputUserData ctx = new ScriptRemoteInputUserData;
  1959. ctx.Write(INPUT_UDT_HAND_REMOTE_EVENT);
  1960. e.WriteToContext(ctx);
  1961. if (LogManager.IsInventoryHFSMLogEnable())
  1962. {
  1963. hndDebugPrint("[hndfsm] send 2 remote: sending e=" + e + " id=" + e.GetEventID() + " p=" + p + " e=" + e.DumpToString());
  1964. }
  1965. p.StoreInputForRemotes(ctx);
  1966. }
  1967. }
  1968. override void OnHandsExitedStableState (HandStateBase src, HandStateBase dst)
  1969. {
  1970. super.OnHandsExitedStableState(src, dst);
  1971. if (LogManager.IsInventoryHFSMLogEnable())
  1972. {
  1973. hndDebugPrint("[hndfsm] hand fsm exit stable src=" + src.Type().ToString());
  1974. }
  1975. }
  1976. override void OnHandsEnteredStableState (HandStateBase src, HandStateBase dst)
  1977. {
  1978. super.OnHandsEnteredStableState(src, dst);
  1979. if (LogManager.IsInventoryHFSMLogEnable())
  1980. {
  1981. hndDebugPrint("[hndfsm] hand fsm entered stable dst=" + dst.Type().ToString());
  1982. }
  1983. }
  1984. override void OnHandsStateChanged (HandStateBase src, HandStateBase dst)
  1985. {
  1986. super.OnHandsStateChanged(src, dst);
  1987. if (LogManager.IsInventoryHFSMLogEnable())
  1988. {
  1989. hndDebugPrint("[hndfsm] hand fsm changed state src=" + src.Type().ToString() + " ---> dst=" + dst.Type().ToString());
  1990. }
  1991. if (src.IsIdle())
  1992. OnHandsExitedStableState(src, dst);
  1993. if (dst.IsIdle())
  1994. OnHandsEnteredStableState(src, dst);
  1995. #ifdef DIAG_DEVELOPER
  1996. PlayerBase p = PlayerBase.Cast(GetDayZPlayerOwner());
  1997. if (p && p.m_Bot)
  1998. {
  1999. p.m_Bot.ProcessEvent(new BotEventOnItemInHandsChanged(p));
  2000. }
  2001. #endif
  2002. }
  2003. override bool HandEvent(InventoryMode mode, HandEventBase e)
  2004. {
  2005. if (!IsProcessing())
  2006. {
  2007. EntityAI itemInHands = GetEntityInHands();
  2008. InventoryLocation handInventoryLocation();
  2009. handInventoryLocation.SetHands(GetInventoryOwner(), itemInHands);
  2010. InventoryValidation validation();
  2011. if (e.CanPerformEventEx(validation))
  2012. {
  2013. m_DeferredEvent = new DeferredHandEvent(mode, e);
  2014. if (m_DeferredEvent.ReserveInventory(this))
  2015. {
  2016. return true;
  2017. }
  2018. }
  2019. m_DeferredEvent = null;
  2020. //! Let the client know a failure happened
  2021. if (!GetGame().IsMultiplayer() || GetGame().IsClient())
  2022. {
  2023. //! If singleplayer or the client is executing this
  2024. OnInventoryFailure(InventoryCommandType.HAND_EVENT, validation.m_Reason, e.GetSrc(), e.GetDst());
  2025. }
  2026. else
  2027. {
  2028. ScriptInputUserData serializer();
  2029. InventoryInputUserData.SerializeHandEvent(serializer, e);
  2030. serializer.Write(validation.m_Reason);
  2031. GetDayZPlayerOwner().SendSyncJuncture(DayZPlayerSyncJunctures.SJ_INVENTORY_FAILURE, serializer);
  2032. }
  2033. }
  2034. return false;
  2035. }
  2036. void HandleHandEvent(DeferredEvent deferred_event)
  2037. {
  2038. //! Default structure suffices
  2039. InventoryValidation validation();
  2040. DeferredHandEvent deferred_hand_event = DeferredHandEvent.Cast(deferred_event);
  2041. if (deferred_hand_event)
  2042. {
  2043. #ifdef ENABLE_LOGGING
  2044. if (LogManager.IsInventoryHFSMLogEnable())
  2045. {
  2046. Debug.InventoryHFSMLog("STS = " + GetDayZPlayerOwner().GetSimulationTimeStamp(), "n/a" , "n/a", "HandleHandEvent", GetDayZPlayerOwner().ToString());
  2047. }
  2048. #endif
  2049. if (LogManager.IsInventoryHFSMLogEnable())
  2050. {
  2051. hndDebugPrint("[inv] HumanInventory::HandEvent(" + typename.EnumToString(InventoryMode, deferred_hand_event.m_mode) + ") ev=" + deferred_hand_event.m_event.DumpToString());
  2052. }
  2053. switch (deferred_hand_event.m_mode)
  2054. {
  2055. case InventoryMode.PREDICTIVE:
  2056. #ifdef ENABLE_LOGGING
  2057. if (LogManager.IsInventoryHFSMLogEnable())
  2058. {
  2059. Debug.InventoryHFSMLog("PREDICTIVE", "n/a" , "n/a", "HandleHandEvent", GetDayZPlayerOwner().ToString());
  2060. }
  2061. #endif
  2062. deferred_hand_event.ClearInventoryReservation(this);
  2063. if (deferred_hand_event.m_event.CanPerformEventEx(validation))
  2064. {
  2065. InventoryInputUserData.SendInputUserDataHandEvent(deferred_hand_event.m_event);
  2066. ProcessHandEvent(deferred_hand_event.m_event);
  2067. }
  2068. break;
  2069. case InventoryMode.JUNCTURE:
  2070. #ifdef ENABLE_LOGGING
  2071. if (LogManager.IsInventoryHFSMLogEnable())
  2072. {
  2073. Debug.InventoryHFSMLog("JUNCTURE", "n/a" , "n/a", "HandleHandEvent", GetDayZPlayerOwner().ToString());
  2074. }
  2075. #endif
  2076. deferred_hand_event.ClearInventoryReservation(this);
  2077. if (deferred_hand_event.m_event.CanPerformEventEx(validation))
  2078. {
  2079. deferred_hand_event.ReserveInventory(this);
  2080. InventoryInputUserData.SendInputUserDataHandEvent(deferred_hand_event.m_event);
  2081. //Functionality to prevent desync when two players perform interfering action at the same time
  2082. EntityAI itemSrc = deferred_hand_event.m_event.GetSrcEntity();
  2083. EntityAI itemDst = null;
  2084. if (deferred_hand_event.m_event.GetDst())
  2085. itemDst = deferred_hand_event.m_event.GetDst().GetItem();
  2086. if (itemSrc)
  2087. EnableMovableOverride(itemSrc);
  2088. if (itemDst)
  2089. EnableMovableOverride(itemDst);
  2090. }
  2091. break;
  2092. case InventoryMode.LOCAL:
  2093. #ifdef ENABLE_LOGGING
  2094. if (LogManager.IsInventoryHFSMLogEnable())
  2095. {
  2096. Debug.InventoryHFSMLog("LOCAL", "n/a" , "n/a", "HandleHandEvent", GetDayZPlayerOwner().ToString());
  2097. }
  2098. #endif
  2099. deferred_hand_event.ClearInventoryReservation(this);
  2100. ProcessHandEvent(deferred_hand_event.m_event);
  2101. //PostHandEvent(deferred_hand_event.m_event);
  2102. break;
  2103. case InventoryMode.SERVER:
  2104. #ifdef ENABLE_LOGGING
  2105. if (LogManager.IsInventoryHFSMLogEnable())
  2106. {
  2107. Debug.InventoryHFSMLog("SERVER", "n/a" , "n/a", "HandleHandEvent", GetDayZPlayerOwner().ToString());
  2108. }
  2109. if (LogManager.IsInventoryHFSMLogEnable())
  2110. {
  2111. hndDebugPrint("[inv] DZPI::HandEvent(" + typename.EnumToString(InventoryMode, deferred_hand_event.m_mode) + ")");
  2112. }
  2113. #endif
  2114. if (!deferred_hand_event.m_event.IsServerSideOnly())
  2115. {
  2116. if (GetDayZPlayerOwner().IsAlive())
  2117. {
  2118. SendServerHandEventViaJuncture(GetDayZPlayerOwner(), deferred_hand_event.m_event);
  2119. }
  2120. else
  2121. {
  2122. InventoryInputUserData.SendServerHandEventViaInventoryCommand(GetDayZPlayerOwner(), deferred_hand_event.m_event);
  2123. }
  2124. }
  2125. else
  2126. {
  2127. ProcessHandEvent(deferred_hand_event.m_event);
  2128. }
  2129. break;
  2130. default:
  2131. Error("HumanInventory::HandEvent - Invalid mode");
  2132. }
  2133. }
  2134. }
  2135. override void HandleInventoryManipulation()
  2136. {
  2137. super.HandleInventoryManipulation();
  2138. if(m_DeferredEvent && ScriptInputUserData.CanStoreInputUserData() )
  2139. {
  2140. HandleHandEvent(m_DeferredEvent);
  2141. HandleTakeToDst(m_DeferredEvent);
  2142. HandleSwapEntities(m_DeferredEvent);
  2143. HandleForceSwapEntities(m_DeferredEvent);
  2144. m_DeferredEvent = null;
  2145. }
  2146. }
  2147. bool IsProcessing()
  2148. {
  2149. return !m_FSM.GetCurrentState().IsIdle() || m_DeferredEvent || m_DeferredPostedHandEvent;
  2150. }
  2151. bool PlayerCheckRequestSrc ( notnull InventoryLocation src, float radius )
  2152. {
  2153. bool result = true;
  2154. EntityAI ent = src.GetParent();
  2155. if ( ent )
  2156. {
  2157. PlayerBase player = PlayerBase.Cast(ent.GetHierarchyRootPlayer());
  2158. if (player)
  2159. {
  2160. if ( GetDayZPlayerOwner() != player )
  2161. {
  2162. if (player.IsAlive())
  2163. {
  2164. if (!player.IsRestrained() && !player.IsUnconscious())
  2165. {
  2166. return false;
  2167. }
  2168. }
  2169. }
  2170. }
  2171. }
  2172. if ( result )
  2173. {
  2174. result = CheckRequestSrc( GetManOwner(), src, radius);
  2175. }
  2176. return result;
  2177. }
  2178. bool PlayerCheckRequestDst ( notnull InventoryLocation src, notnull InventoryLocation dst, float radius )
  2179. {
  2180. bool result = true;
  2181. EntityAI ent = dst.GetParent();
  2182. if ( ent )
  2183. {
  2184. PlayerBase player = PlayerBase.Cast(ent.GetHierarchyRootPlayer());
  2185. if (player)
  2186. {
  2187. if ( GetDayZPlayerOwner() != player )
  2188. {
  2189. if (player.IsAlive())
  2190. {
  2191. if (!player.IsRestrained() && !player.IsUnconscious())
  2192. {
  2193. return false;
  2194. }
  2195. }
  2196. }
  2197. }
  2198. }
  2199. if ( result )
  2200. {
  2201. result = CheckMoveToDstRequest( GetManOwner(), src, dst, radius);
  2202. }
  2203. return result;
  2204. }
  2205. bool PlayerCheckSwapItemsRequest( notnull InventoryLocation src1, notnull InventoryLocation src2, notnull InventoryLocation dst1, notnull InventoryLocation dst2, float radius)
  2206. {
  2207. bool result = true;
  2208. EntityAI ent = dst1.GetParent();
  2209. PlayerBase player;
  2210. if ( ent )
  2211. {
  2212. player = PlayerBase.Cast(ent.GetHierarchyRootPlayer());
  2213. if (player)
  2214. {
  2215. if ( GetDayZPlayerOwner() != player )
  2216. {
  2217. if (player.IsAlive())
  2218. {
  2219. if (!player.IsRestrained() && !player.IsUnconscious())
  2220. {
  2221. return false;
  2222. }
  2223. }
  2224. }
  2225. }
  2226. }
  2227. ent = dst2.GetParent();
  2228. if ( ent )
  2229. {
  2230. player = PlayerBase.Cast(ent.GetHierarchyRootPlayer());
  2231. if (player)
  2232. {
  2233. if ( GetDayZPlayerOwner() != player )
  2234. {
  2235. if (player.IsAlive())
  2236. {
  2237. if (!player.IsRestrained() && !player.IsUnconscious())
  2238. {
  2239. return false;
  2240. }
  2241. }
  2242. }
  2243. }
  2244. }
  2245. if ( result )
  2246. {
  2247. result = CheckSwapItemsRequest( GetManOwner(), src1, src2, dst1, dst2, GameInventory.c_MaxItemDistanceRadius);
  2248. }
  2249. return result;
  2250. }
  2251. bool PlayerCheckDropRequest ( notnull InventoryLocation src, float radius )
  2252. {
  2253. bool result = true;
  2254. EntityAI ent = src.GetParent();
  2255. if ( ent )
  2256. {
  2257. PlayerBase player = PlayerBase.Cast(ent.GetHierarchyRootPlayer());
  2258. if (player)
  2259. {
  2260. if ( GetDayZPlayerOwner() != player )
  2261. {
  2262. if (player.IsAlive())
  2263. {
  2264. if (!player.IsRestrained() && !player.IsUnconscious())
  2265. {
  2266. return false;
  2267. }
  2268. }
  2269. }
  2270. }
  2271. }
  2272. if ( result )
  2273. {
  2274. result = CheckDropRequest( GetManOwner(), src, radius);
  2275. }
  2276. return result;
  2277. }
  2278. };