1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package Player.PlayerGoldRush
#
# @todo:ÌÔ½ð
# @author hxp
# @date 2025-09-03
# @version 1.0
#
# ÏêϸÃèÊö: ÌÔ½ð
#
#-------------------------------------------------------------------------------
#"""Version = 2025-09-03 15:30"""
#-------------------------------------------------------------------------------
 
import ChConfig
import GameWorld
import NetPackCommon
import IpyGameDataPY
import ItemControler
import ChPyNetSendPack
import PlayerControl
import GameFuncComm
import ShareDefine
import ObjPool
 
import time
import math
 
def OnPlayerLogin(curPlayer):
    __CheckGoldRushFreeUnlock(curPlayer)
    SyncGoldRushInfo(curPlayer)
    SyncGoldCampInfo(curPlayer)
    return
 
def __CheckGoldRushFreeUnlock(curPlayer):
    ## ¼ì²éĬÈϽâËø£¬¼´Ã»ÓнâËøÌõ¼þµÄ£¬ÓÐÌõ¼þµÄÐèÒªÊÖ¶¯½âËø
    
    playerID = curPlayer.GetPlayerID()
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    campState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GoldRushCampState)
    for index in range(ipyDataMgr.GetGoldRushCampCount()):
        ipyData = ipyDataMgr.GetGoldRushCampByIndex(index)
        campID = ipyData.GetCampID()
        if campState & pow(2, campID):
            continue
        if ipyData.GetPanningUnlock() or ipyData.GetMoneyUnlock():
            #ÓнâËøÌõ¼þµÄ²»ÅжÏ
            continue
        campState |= pow(2, campID)
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GoldRushCampState, campState)
        GameWorld.DebugLog("ĬÈϽâËøÌÔ½ðÓªµØ: campID=%s,campState=%s" % (campID, campState), playerID)
        
    workerState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GoldRushWorkerState)
    for index in range(ipyDataMgr.GetGoldRushWorkerCount()):
        ipyData = ipyDataMgr.GetGoldRushWorkerByIndex(index)
        workerID = ipyData.GetWorkerID()
        if workerState & pow(2, workerID):
            continue
        if ipyData.GetPlayerLVUnlock() or ipyData.GetMoneyUnlock():
            #ÓнâËøÌõ¼þµÄ²»ÅжÏ
            continue
        workerState |= pow(2, workerID)
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GoldRushWorkerState, workerState)
        GameWorld.DebugLog("ĬÈϽâËøÌÔ½ð¼à¹¤: workerID=%s,workerState=%s" % (workerID, workerState), playerID)
        
    return
 
def OnProcess(curPlayer):
    CheckGoldPushEnergyRecover(curPlayer)
    CheckGoldRushCamp(curPlayer)
    return
 
def GetCampInfo(curPlayer, campID):
    ## ÓªµØÐÅÏ¢
    # ÒÑˢдÎÊý*1000+ÌÔ½ðID*10+ÅÉDz¹¤ÈËÊý
    # @return refreshCnt, goldID, workerCnt
    campInfo = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GoldRushCampInfo % campID)
    refreshCnt = campInfo / 1000
    goldID = campInfo % 1000 / 10
    workerCnt = campInfo % 10
    return refreshCnt, goldID, workerCnt
 
def SetCampInfo(curPlayer, campID, refreshCnt, goldID, workerCnt, isNotify=True):
    ## ÉèÖñ£´æÓªµØÐÅÏ¢
    campInfo = refreshCnt * 1000 + min(goldID, 99) * 10 + workerCnt
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GoldRushCampInfo % campID, campInfo)
    if isNotify:
        SyncGoldCampInfo(curPlayer, [campID])
    return campInfo
 
def GoldRushAutoCanUse(curPlayer):
    ## ×Ô¶¯ÌÔ½ðÊÇ·ñ¿ÉÓÃ
    endTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GoldRushAutoEndTime)
    return int(time.time()) <= endTime
 
#// B0 36 ÌÔ½ð²Ù×÷ #tagCSGoldRushOP
#
#struct    tagCSGoldRushOP
#{
#    tagHead        Head;
#    BYTE        OPType;        // 0-½ÓÊÜÌÔ½ð£»1-Ë¢ÐÂÌÔ½ð£»2-¿ªÊ¼ÌÔ½ð»òµ÷Õû¼à¹¤Êý£»3-È¡ÏûÌÔ½ð£»
#    BYTE        CampID;        // ÓªµØID
#    BYTE        WorkerCnt;    // ÅÉDz¼à¹¤Êý£¬½öÀàÐÍ2ÓÐЧ
#};
def OnGoldRushOP(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    OPType = clientData.OPType
    campID = clientData.CampID
    workerCnt = clientData.WorkerCnt
    
    campState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GoldRushCampState)
    if not campState & pow(2, campID):
        GameWorld.DebugLog("¸ÃÓªµØÎ´½âËø! campID=%s,campState=%s" % (campID, campState))
        return
    
    if OPType == 0: # 0-½ÓÊÜÌÔ½ð
        __onGoldRushAccept(curPlayer, campID)
    elif OPType == 1: # 1-Ë¢ÐÂÌÔ½ð
        __onGoldRushRefresh(curPlayer, campID)
    elif OPType == 2: # 2-¿ªÊ¼ÌÔ½ð»òµ÷Õû¼à¹¤Êý
        __onGoldRushStart(curPlayer, campID, workerCnt)
    elif OPType == 3: # 3-È¡ÏûÌÔ½ð
        __onGoldRushCancel(curPlayer, campID)
        
    return
 
def __onGoldRushAccept(curPlayer, campID):
    ## ½ÓÊÜ
    refreshCnt, goldID, workerCnt = GetCampInfo(curPlayer, campID)
    if goldID:
        GameWorld.DebugLog("¸ÃÓªµØÒѾ­ÓÐË¢ÐÂÌÔ½ðÁË£¬²»ÄܽÓÊÜ! campID=%s,goldID=%s" % (campID, goldID))
        return
    ipyData = GetRefreshGoldItemIpyData(curPlayer)
    if not ipyData:
        return
    # ½ÓÊÜÌÔ½ð²»ÊÜÆäËûÏÞÖÆ£¬ÓÐÌåÁ¦¾ÍÐÐ
    needMoney = IpyGameDataPY.GetFuncCfg("GoldRushRefresh", 1) # ÐèÒªÌÔ½ðÁîÊýÁ¿
    if not PlayerControl.PayMoney(curPlayer, ShareDefine.TYPE_Price_GoldRushEnergy, needMoney):
        return
    goldID = ipyData.GetGoldID()
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GoldRushCampEndTime % campID, 0)
    campInfo = SetCampInfo(curPlayer, campID, refreshCnt, goldID, workerCnt)
    GameWorld.DebugLog("½ÓÊÜÌÔ½ð: campID=%s,goldID=%s,campInfo=%s" % (campID, goldID, campInfo))
    CheckGoldPushEnergyRecover(curPlayer, False)
    SyncGoldRushInfo(curPlayer)
    return
 
def InitGoldEnergy(curPlayer):
    energyList = IpyGameDataPY.GetFuncEvalCfg("GoldRush", 2)
    maxEnergy = sum(energyList) if GoldRushAutoCanUse(curPlayer) else energyList[0]
    curEnergy = PlayerControl.GetMoney(curPlayer, ShareDefine.TYPE_Price_GoldRushEnergy)
    if curEnergy >= maxEnergy:
        return
    addEnergy = maxEnergy - curEnergy
    PlayerControl.GiveMoney(curPlayer, ShareDefine.TYPE_Price_GoldRushEnergy, addEnergy)
    GameWorld.DebugLog("ÌÔ½ð³õʼ»¯: addEnergy=%s" % addEnergy)
    return
 
def CheckGoldPushEnergyRecover(curPlayer, isNotify=True):
    ## ¼ì²éÌåÁ¦»Ö¸´
    energyList = IpyGameDataPY.GetFuncEvalCfg("GoldRush", 2)
    maxEnergy = sum(energyList) if GoldRushAutoCanUse(curPlayer) else energyList[0]
    curEnergy = PlayerControl.GetMoney(curPlayer, ShareDefine.TYPE_Price_GoldRushEnergy)
    lastRecoverTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GoldRushRecoverTime)
    if curEnergy >= maxEnergy:
        if lastRecoverTime:
            GameWorld.DebugLog("ÌÔ½ðÌåÁ¦ÒÑÂú!")
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GoldRushRecoverTime, 0)
            isNotify and SyncGoldRushInfo(curPlayer)
        return
    
    curTime = int(time.time())
    passSeconds = curTime - lastRecoverTime
    if not lastRecoverTime or passSeconds < 0:
        GameWorld.DebugLog("ÖØÉèÌÔ½ðÌåÁ¦»Ö¸´Ê±¼ä!")
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GoldRushRecoverTime, curTime)
        isNotify and SyncGoldRushInfo(curPlayer)
        return
    
    cdSeconds = IpyGameDataPY.GetFuncCfg("GoldRush", 3) * 60
    if passSeconds < cdSeconds:
        return
    recoverCnt = passSeconds / cdSeconds
    updRecoverTime = curTime - passSeconds % cdSeconds
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GoldRushRecoverTime, updRecoverTime)
    GameWorld.DebugLog("»Ö¸´ÌÔ½ðÁî: %s,passSeconds=%s,Éϴλָ´:%s" % (recoverCnt, passSeconds, GameWorld.ChangeTimeNumToStr(lastRecoverTime)))
    PlayerControl.GiveMoney(curPlayer, ShareDefine.TYPE_Price_GoldRushEnergy, recoverCnt)
    if PlayerControl.GetMoney(curPlayer, ShareDefine.TYPE_Price_GoldRushEnergy) >= maxEnergy:
        GameWorld.DebugLog("ÌåÁ¦ÒÑÂú!")
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GoldRushRecoverTime, 0)
    isNotify and SyncGoldRushInfo(curPlayer)
    return
 
def GetRefreshGoldItemIpyData(curPlayer):
    ## »ñÈ¡Ëæ»úˢеÄÌÔ½ðÎïÆ·IpyData
    funcLimitDict = IpyGameDataPY.GetFuncEvalCfg("GoldRushRefresh", 5, {})
    weightList = []
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    for index in range(ipyDataMgr.GetGoldRushItemCount()):
        ipyData = ipyDataMgr.GetGoldRushItemByIndex(index)
        #goldID = ipyData.GetGoldID()
        itemID = ipyData.GetItemID()
        weight = ipyData.GetRefreshWeight()
        if not weight:
            continue
        if str(itemID) in funcLimitDict:
            funcID = funcLimitDict[str(itemID)]
            if not GameFuncComm.GetFuncCanUse(curPlayer, funcID):
                continue
        weightList.append([weight, ipyData])
    return GameWorld.GetResultByWeightList(weightList)
 
def __onGoldRushRefresh(curPlayer, campID):
    ## Ë¢ÐÂ
    refreshCnt, goldID, workerCnt = GetCampInfo(curPlayer, campID)
    if not goldID:
        __onGoldRushAccept(curPlayer, campID)
        return
    if workerCnt:
        GameWorld.DebugLog("ÌÔ½ðÖУ¬²»ÄÜË¢ÐÂ! campID=%s,workerCnt=%s" % (campID, workerCnt))
        return
    moneyType = IpyGameDataPY.GetFuncCfg("GoldRushRefresh", 2)
    needMoneyList = IpyGameDataPY.GetFuncEvalCfg("GoldRushRefresh", 3)
    if not moneyType or not needMoneyList:
        return
    needMoney = needMoneyList[refreshCnt] if len(needMoneyList) > refreshCnt else needMoneyList[-1]
    ipyData = GetRefreshGoldItemIpyData(curPlayer)
    if not ipyData:
        return
    goldID = ipyData.GetGoldID()
    if needMoney and not PlayerControl.PayMoney(curPlayer, moneyType, needMoney):
        return
    refreshCnt += 1
    campInfo = SetCampInfo(curPlayer, campID, refreshCnt, goldID, workerCnt)
    GameWorld.DebugLog("ÌÔ½ðÓªµØÊÖ¶¯Ë¢ÐÂ: campID=%s,goldID=%s,refreshCnt=%s,campInfo=%s,needMoney=%s" % (campID, goldID, refreshCnt, campInfo, needMoney))
    return
 
def __onGoldRushStart(curPlayer, campID, setWorkerCnt):
    ## ¿ªÊ¼/ÐÞ¸Ä
    refreshCnt, goldID, workerCnt = GetCampInfo(curPlayer, campID)
    if not goldID:
        GameWorld.DebugLog("ÓªµØÎª¿Õ£¬ÎÞ·¨¿ªÊ¼»òÐÞ¸Ä! campID=%s" % (campID))
        return
    
    if workerCnt == setWorkerCnt:
        GameWorld.DebugLog("ÓªµØ¹¤ÈËÏàͬ£¬ÎÞÐèÐÞ¸Ä! campID=%s" % (campID))
        return
    
    goldIpyData = IpyGameDataPY.GetIpyGameData("GoldRushItem", goldID)
    if not goldIpyData:
        return
    
    # ½øÐÐÖеÄ
    panningCnt = 0
    atWorkCnt = 0 # ¹¤×÷ÖеŤÈË£¬²»º¬±¾ÓªµØ
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    for index in range(ipyDataMgr.GetGoldRushCampCount()):
        ipyData = ipyDataMgr.GetGoldRushCampByIndex(index)
        cID = ipyData.GetCampID()
        _, gID, wCnt = GetCampInfo(curPlayer, cID)
        if gID and wCnt:
            panningCnt += 1
            if campID != cID:
                atWorkCnt += wCnt
            
    workersTotal = 0 # ×ܹ¤ÈËÊý
    workerState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GoldRushWorkerState)
    for index in range(ipyDataMgr.GetGoldRushWorkerCount()):
        ipyData = ipyDataMgr.GetGoldRushWorkerByIndex(index)
        workerID = ipyData.GetWorkerID()
        if workerState & pow(2, workerID):
            workersTotal += 1
    idleWorkers = workersTotal - atWorkCnt # ¿ÕÏй¤ÈËÊý
    if idleWorkers <= 0:
        GameWorld.DebugLog("ûÓпÕÏй¤ÈË£¬ÎÞ·¨¿ªÊ¼ÌÔ½ð! atWorkCnt=%s >= %s" % (atWorkCnt, workersTotal))
        return
    workerMax = goldIpyData.GetWorkerMax()
    updWorkerCnt = min(idleWorkers, setWorkerCnt, workerMax)
    if updWorkerCnt <= 0:
        GameWorld.DebugLog("¹¤È˲»×ã! setWorkerCnt=%s,idleWorkers=%s" % (setWorkerCnt, idleWorkers))
        return
    
    GameWorld.DebugLog("¿ªÊ¼/ÐÞ¸ÄÌÔ½ð: campID=%s,goldID=%s,setWorkerCnt=%s,workerMax=%s,idleWorkers=%s,updWorkerCnt=%s" 
                       % (campID, goldID, setWorkerCnt, workerMax, idleWorkers, updWorkerCnt))
    
    curTime = int(time.time())
    # Î´¿ªÊ¼µÄ
    if not workerCnt:
        warehouseSpaceList = IpyGameDataPY.GetFuncEvalCfg("GoldRush", 1) # ÌÔ½ð²Ö¿âÉÏÏÞ|×Ô¶¯ÌÔ½ð¿ªÆôÔö¼ÓÉÏÏÞ
        canUseSpaceMax = sum(warehouseSpaceList) if GoldRushAutoCanUse(curPlayer) else warehouseSpaceList[0]
        
        # Î´ÁìÈ¡µÄ
        unGetCnt = 0
        for index in range(sum(warehouseSpaceList)):
            if curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GoldRushWarehouse % index):
                unGetCnt += 1
                
        if (unGetCnt + panningCnt) >= canUseSpaceMax:
            GameWorld.DebugLog("ÌÔ½ð²Ö¿âûÓжàÓà¿Õ¼ä£¬ÎÞ·¨ÌÔ½ð! (δÁìÈ¡(%s) + ÌÔ½ðÖÐ(%s)) >= canUseSpaceMax(%s)" % (unGetCnt, panningCnt, canUseSpaceMax))
            return
        
        needSeconds = goldIpyData.GetNeedSeconds() # µ¥¸ö¹¤ÈËËùÐèʱ¼ä
        GameWorld.DebugLog("    Î´¿ªÊ¼µÄ! µ¥¹¤È˺Äʱ=%s" % (needSeconds))
        
    # ÖÐ;Ð޸ĵÄ
    else:
        endTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GoldRushCampEndTime % campID)
        reaminSeconds = max(0, endTime - curTime) # Ê£Óàʱ¼ä
        needSeconds = reaminSeconds * workerCnt # µ¥¸ö¹¤È˺Äʱ = Ê£Óàʱ¼ä * Ô­ÏȵŤÈËÊý
        GameWorld.DebugLog("    Ð޸ŤÈËÊý! Ô­Ê£ÓàÃë=%s,Ê£Ó൥¹¤È˺Äʱ=%s" % (reaminSeconds, needSeconds))
        
    realNeedSeconds = int(math.ceil(needSeconds / float(updWorkerCnt)))
    endTime = curTime + realNeedSeconds
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GoldRushCampEndTime % campID, endTime)
    campInfo = SetCampInfo(curPlayer, campID, refreshCnt, goldID, updWorkerCnt)
    GameWorld.DebugLog("    updWorkerCnt=%s,realNeedSeconds=%s,endTime=%s,campInfo=%s" 
                       % (updWorkerCnt, realNeedSeconds, GameWorld.ChangeTimeNumToStr(endTime), campInfo))
    return
 
def __onGoldRushCancel(curPlayer, campID):
    ## È¡Ïû
    refreshCnt, goldID, workerCnt = GetCampInfo(curPlayer, campID)
    if not workerCnt:
        GameWorld.DebugLog("·ÇÌÔ½ðÖУ¬²»ÐèҪȡÏû! campID=%s" % (campID))
        return
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GoldRushCampEndTime % campID, 0)
    campInfo = SetCampInfo(curPlayer, campID, refreshCnt, goldID, 0)
    GameWorld.DebugLog("È¡ÏûÌÔ½ð: campID=%s,goldID=%s,workerCnt=%s,campInfo=%s" % (campID, goldID, workerCnt, campInfo))
    return
 
#// B0 37 ÌÔ½ð½âËø #tagCSGoldRushUnlock
#
#struct    tagCSGoldRushUnlock
#{
#    tagHead        Head;
#    BYTE        UnlockType;    // 0-ÓªµØ£»1-¼à¹¤
#    BYTE        UnlockID;        // ½âËøÀàÐͶÔÓ¦µÄID
#};
def OnGoldRushUnlock(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    UnlockType = clientData.UnlockType
    UnlockID = clientData.UnlockID
    if UnlockType == 1:
        __onUnlockWorker(curPlayer, UnlockID)
    else:
        __onUnlockCamp(curPlayer, UnlockID)
    return
 
def __onUnlockCamp(curPlayer, campID):
    campState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GoldRushCampState)
    if campState & pow(2, campID):
        GameWorld.DebugLog("¸ÃÓªµØÒѽâËø! campID=%s,campState=%s" % (campID, campState))
        return
    
    ipyData = IpyGameDataPY.GetIpyGameData("GoldRushCamp", campID)
    if not ipyData:
        return
    
    needCnt = ipyData.GetPanningUnlock()
    panningCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GoldRushCnt)
    if needCnt and panningCnt < needCnt:
        GameWorld.DebugLog("ËùÐèÌÔ½ð´ÎÊý²»×㣬ÎÞ·¨½âËøÓªµØ! campID=%s,panningCnt=%s < %s" % (campID, panningCnt, needCnt))
        return
    
    moneyUnlock = ipyData.GetMoneyUnlock()
    moneyType, costMoney = moneyUnlock if (moneyUnlock and len(moneyUnlock) == 2) else (0, 0)
    if moneyType and costMoney and not PlayerControl.PayMoney(curPlayer, moneyType, costMoney, "GoldRushUnlockCamp"):
        return
    
    campState |= pow(2, campID)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GoldRushCampState, campState)
    GameWorld.DebugLog("½âËøÌÔ½ðÓªµØ: campID=%s,campState=%s" % (campID, campState))
    SyncGoldRushInfo(curPlayer)
    return
 
def __onUnlockWorker(curPlayer, workerID):
    workerState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GoldRushWorkerState)
    if workerState & pow(2, workerID):
        GameWorld.DebugLog("¸Ã¼à¹¤ÒѽâËø! workerID=%s,workerState=%s" % (workerID, workerState))
        return
    
    ipyData = IpyGameDataPY.GetIpyGameData("GoldRushWorker", workerID)
    if not ipyData:
        return
    
    curLV = curPlayer.GetLV()
    needLV = ipyData.GetPlayerLVUnlock()
    if needLV and curLV < needLV:
        GameWorld.DebugLog("ËùÐèµÈ¼¶´ÎÊý²»×㣬ÎÞ·¨½âËø¼à¹¤! workerID=%s,curLV=%s < %s" % (workerID, curLV, needLV))
        return
    
    moneyUnlock = ipyData.GetMoneyUnlock()
    moneyType, costMoney = moneyUnlock if (moneyUnlock and len(moneyUnlock) == 2) else (0, 0)
    if moneyType and costMoney and not PlayerControl.PayMoney(curPlayer, moneyType, costMoney, "GoldRushUnlockWorker"):
        return
    
    workerState |= pow(2, workerID)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GoldRushWorkerState, workerState)
    GameWorld.DebugLog("½âËøÌÔ½ð¼à¹¤: workerID=%s,workerState=%s" % (workerID, workerState))
    SyncGoldRushInfo(curPlayer)
    return
 
#// B0 38 ÌÔ½ð²Ö¿âÁì½± #tagCSGoldRushWarehouseAward
#
#struct    tagCSGoldRushWarehouseAward
#{
#    tagHead        Head;
#    BYTE        AwardIndex;    // Á콱λÖÃË÷Òý£¬´Ó0¿ªÊ¼
#    BYTE        IsAll;        // ÊÇ·ñÁìÈ¡ËùÓÐ
#};
def OnGoldRushWarehouseAward(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    index = clientData.AwardIndex
    isAll = clientData.IsAll
    GameWorld.DebugLog("ÌÔ½ð²Ö¿âÁì½±: index=%s,isAll=%s" % (index, isAll))
    
    getList = []
    if isAll:
        spaceList = IpyGameDataPY.GetFuncEvalCfg("GoldRush", 1)
        maxSpace = sum(spaceList) if GoldRushAutoCanUse(curPlayer) else spaceList[0]
        for index in range(maxSpace):
            goldID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GoldRushWarehouse % index)
            if not goldID:
                continue
            getList.append([index, goldID])
    else:
        goldID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GoldRushWarehouse % index)
        if not goldID:
            GameWorld.DebugLog("¸ÃλÖÃûÓÐÒÑÍêÕûµÄÌÔ½ð½±Àø! index=%s" % index)
            return
        getList.append([index, goldID])
        
    if not getList:
        return
    
    giveItemDict = {}
    for index, goldID in getList:
        goldIpyData = IpyGameDataPY.GetIpyGameData("GoldRushItem", goldID)
        if not goldIpyData:
            continue
        itemID = goldIpyData.GetItemID()
        itemCount = goldIpyData.GetItemCount()
        giveItemDict[itemID] = giveItemDict.get(itemID, 0) + itemCount
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GoldRushWarehouse % index, 0)
        GameWorld.DebugLog("    index=%s,goldID=%s,itemID=%s,itemCount=%s" % (index, goldID, itemID, itemCount))
        
    itemList = [[itemID, itemCount] for itemID, itemCount in giveItemDict.items()]        
    GameWorld.DebugLog("    giveItemDict=%s,itemList=%s" % (giveItemDict, itemList))
    
    SyncGoldRushInfo(curPlayer)
    ItemControler.GivePlayerItemOrMail(curPlayer, itemList, event=["GoldRush", False, {}])
    return
 
def CheckGoldRushCamp(curPlayer):
    ## ¼ì²éÓªµØÌÔ½ð
    curTime = int(time.time())
    endCampList = []
    emptyCampList = []
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    for index in range(ipyDataMgr.GetGoldRushCampCount()):
        ipyData = ipyDataMgr.GetGoldRushCampByIndex(index)
        campID = ipyData.GetCampID()
        _, goldID, _ = GetCampInfo(curPlayer, campID)
        endTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GoldRushCampEndTime % campID)
        if not goldID:
            emptyCampList.append([campID, endTime])
            continue
        if not endTime:
            continue
        if curTime < endTime:
            continue
        endCampList.append([campID, goldID])
        
    if endCampList:
        __doEndCamp(curPlayer, endCampList, curTime)
        
    if emptyCampList:
        __doSysRefreshCampGold(curPlayer, emptyCampList, curTime)
        
    return
 
def __doEndCamp(curPlayer, endCampList, curTime):
    syncCampIDList = []
    spaceList = IpyGameDataPY.GetFuncEvalCfg("GoldRush", 1)
    maxSpace = sum(spaceList) if GoldRushAutoCanUse(curPlayer) else spaceList[0]
    for index in range(maxSpace):
        if not endCampList:
            break
        if curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GoldRushWarehouse % index):
            continue
        campID, goldID = endCampList.pop(0)
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GoldRushWarehouse % index, goldID)
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GoldRushCampEndTime % campID, curTime) # ÔٴθüÐÂendTime
        panningCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GoldRushCnt) + 1
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GoldRushCnt, panningCnt)
        SetCampInfo(curPlayer, campID, 0, 0, 0, False)
        syncCampIDList.append(campID)
        GameWorld.DebugLog("ÌÔ½ð½áÊø: campID=%s,goldID=%s,·ÅÈëÌÔ½ð²Ö¿âindex=%s,panningCnt=%s" % (campID, goldID, index, panningCnt))
        
    if not syncCampIDList:
        return
    
    SyncGoldCampInfo(curPlayer, syncCampIDList)
    SyncGoldRushInfo(curPlayer)
    return
 
def __doSysRefreshCampGold(curPlayer, emptyCampList, curTime):
    ## ÏµÍ³×Ô¶¯Ë¢ÐÂÓªµØ½ð¿ó
    sysRefreshCD = IpyGameDataPY.GetFuncCfg("GoldRushRefresh", 4) * 60
    if not sysRefreshCD:
        return
    
    syncCampIDList = []
    refreshCnt, workerCnt = 0, 0
    for campID, endTime in emptyCampList:
        if endTime and (curTime - endTime) < sysRefreshCD:
            #GameWorld.DebugLog("ϵͳ×Ô¶¯Ë¢ÐÂÌÔ½ðÓªµØ½ð¿óCDδµ½: campID=%s,endTime=%s,sysRefreshCD=%s > %s" % (campID, endTime, sysRefreshCD, curTime - endTime))
            continue
        
        ipyData = GetRefreshGoldItemIpyData(curPlayer)
        if not ipyData:
            continue
        
        goldID = ipyData.GetGoldID()
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GoldRushCampEndTime % campID, 0)
        campInfo = SetCampInfo(curPlayer, campID, refreshCnt, goldID, workerCnt, False)
        GameWorld.DebugLog("ϵͳ×Ô¶¯Ë¢ÐÂÌÔ½ðÓªµØ½ð¿ó: campID=%s,goldID=%s,campInfo=%s" % (campID, goldID, campInfo))
        syncCampIDList.append(campID)
        
    if syncCampIDList:
        SyncGoldCampInfo(curPlayer, syncCampIDList)
        
    return
 
#// B0 39 ×Ô¶¯ÌÔ½ðÃâ·ÑʹÓà#tagCSGoldRushAutoFreeUse
#
#struct    tagCSGoldRushAutoFreeUse
#{
#    tagHead        Head;
#};
def OnGoldRushAutoFreeUse(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    OnActGoldRushAuto(curPlayer, 0)
    return
 
def OnGoldRushByCTGID(curPlayer, ctgID):
    keeperCTGIDList = IpyGameDataPY.GetFuncEvalCfg("GoldRushAuto", 2)
    for keeperIndex, ctgIDList in enumerate(keeperCTGIDList, 1):
        if ctgID in ctgIDList:
            OnActGoldRushAuto(curPlayer, keeperIndex)
            break
    return
 
def OnActGoldRushAuto(curPlayer, keeperIndex):
    ## ¼¤»î/Ôö¼Ó×Ô¶¯¹Ü¼Òʱ³¤
    # @param keeperIndex: ¹Ü¼ÒµµÎ»Ë÷Òý£¬0-Ãâ·Ñ£¬>0-¸¶·Ñµµ
    
    playerID = curPlayer.GetPlayerID()
    endTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GoldRushAutoEndTime)
    if keeperIndex == 0:
        if endTime:
            GameWorld.DebugLog("ÌÔ½ðÃâ·Ñ¹Ü¼ÒÒÑÁìÈ¡¹ý£¡", playerID)
            return
        
    keeperDaysList = IpyGameDataPY.GetFuncEvalCfg("GoldRushAuto", 1)
    if keeperIndex < 0 or keeperIndex >= len(keeperDaysList):
        return
    addDays = keeperDaysList[keeperIndex]
    addSeconds = addDays * 24 * 3600
    curTime = int(time.time())
    
    endTimeStr = GameWorld.ChangeTimeNumToStr(endTime) if endTime else ""
    GameWorld.DebugLog("¼¤»îÌÔ½ð¹Ü¼Ò: keeperIndex=%s,addDays=%s(%s)" % (keeperIndex, addDays, addSeconds), playerID)
    GameWorld.DebugLog("    ¹Ü¼Òµ½ÆÚʱ¼ä: endTime=%s, %s" % (endTime, endTimeStr), playerID)
    if not endTime:
        updEndTime = curTime + addSeconds
        GameWorld.DebugLog("    ¼¤»î¹Ü¼Ò", playerID)
    elif curTime >= endTime:
        updEndTime = curTime + addSeconds 
        GameWorld.DebugLog("    ÒѹýÆÚ£¬ÖØÐ¼¤»î¹Ü¼Ò", playerID)
    else:
        updEndTime = endTime + addSeconds
        GameWorld.DebugLog("    Ðø·Ñ¹Ü¼Òʱ³¤", playerID)
        
    GameWorld.DebugLog("    ¸üйܼҵ½ÆÚʱ¼ä: updEndTime=%s, %s" % (updEndTime, GameWorld.ChangeTimeNumToStr(updEndTime)), playerID)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GoldRushAutoEndTime, updEndTime)
    SyncGoldRushInfo(curPlayer)
    return
 
def SyncGoldRushInfo(curPlayer):
    clientPack = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagSCGoldRushInfo)
    clientPack.CampState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GoldRushCampState)
    clientPack.WorkerState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GoldRushWorkerState)
    clientPack.PanningCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GoldRushCnt)
    clientPack.LastRecoverTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GoldRushRecoverTime)
    clientPack.HousekeeperEndTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GoldRushAutoEndTime)
    clientPack.WarehouseIDList = []
    for index in range(sum(IpyGameDataPY.GetFuncEvalCfg("GoldRush", 1))):
        goldID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GoldRushWarehouse % index)
        clientPack.WarehouseIDList.append(goldID)
    clientPack.WarehouseCnt = len(clientPack.WarehouseIDList)
    NetPackCommon.SendFakePack(curPlayer, clientPack)
    return
 
def SyncGoldCampInfo(curPlayer, syncCampIDList=None):
    poolMgr = ObjPool.GetPoolMgr()
    campList = []
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    for index in range(ipyDataMgr.GetGoldRushCampCount()):
        ipyData = ipyDataMgr.GetGoldRushCampByIndex(index)
        campID = ipyData.GetCampID()
        if syncCampIDList and campID not in syncCampIDList:
            continue
        refreshCnt, goldID, workerCnt = GetCampInfo(curPlayer, campID)
        camp = poolMgr.acquire(ChPyNetSendPack.tagSCGoldRushCamp)
        camp.CampID = campID
        camp.GoldID = goldID
        camp.RefreshCnt = refreshCnt
        camp.WorkerCnt = workerCnt
        camp.EndTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GoldRushCampEndTime % campID)
        campList.append(camp)
    if not campList:
        return
    clientPack = poolMgr.acquire(ChPyNetSendPack.tagSCGoldRushCampInfo)
    clientPack.CampList = campList
    clientPack.CampCnt = len(clientPack.CampList)
    NetPackCommon.SendFakePack(curPlayer, clientPack)
    return