Server can crash when picking up weapons

Issue #253 resolved
Andrew Theel created an issue

```UServerCommandlet::Main DH_M1CarbineWeapon DH-Stavelot.DH_M1CarbineWeapon (Function Engine.Weapon.MaxAmmo:0001) Runaway loop detected (over 10000000 iterations)

History: FFrame::Serialize <- UObject::ProcessEvent <- (DHPlayer DH-Stavelot.DHPlayer, Function ROEngine.ROPlayer.ServerUse) <- RemoteCall <- HandleStream <- UActorChannel::Receive dBunch <- (Actor DHPlayer) <- UChannel::ReceivedSequencedBunch <- Direct <- UChannel::ReceivedRawBunch <- DispatchDataToChannel <- BunchData <- UNetConnection::ReceivedPacket <- UN etConnection::ReceivedRawPacket <- UTcpNetDriver::TickDispatch <- UpdatePreNet <- ULevel::Tick <- (NetMode=1) <- TickLevel <- UGameEngine::Tick <- Level Stavelot <- UpdateWorld <- UServerCommandlet::Main

Exiting due to error Exiting. FileManager: Reading 0 GByte 734 MByte 468 KByte 58 Bytes from HD took 30.256235 seconds (30.076235 reading, 0.180000 seeking). FileManager: 1.868027 seconds spent with misc. duties Name subsystem shut down Press any key to continue . . .```

Comments (11)

  1. Matt Hands

    Looking at possible code culprits, were you picking up a carbine from the ground? Perhaps already having a carbine, so the pickup would just give you extra mags for it? (I'm looking at a while loop in HandlePickupQuery).

    If not, can you describe the situation, e.g. selecting the weapon, resupplying at ammo dump, reloading, etc. Just to give me a head start in where to look.

  2. Andrew Theel reporter

    I wasn't on the server, others were, I was busy and will be busy tomorrow and next week. Just trying to keep things rolling along on this front. My class is almost over, then I will hit DH hard like Thor's hammer.

  3. Colin Basnett

    I have made a variety of bug fixes to the pickup system and this bug has not been encountered since it was originally reported. Marking as resolved, but not sure what resolved it. If this occurs again, we can re-open this.

  4. Colin Basnett

    I did some investigating and found the cause of this. The problem is a particular loop in DHProjectileWeapon's HandlePickupQuery function.

    // First, we'll look for any fairly full mags to pick up
    while (PrimaryAmmoArray.Length < MaxNumPrimaryMags && DHWP.AmmoMags.Length > 0)
    {
        i = ++i % DHWP.AmmoMags.Length; // cycle to next pickup mag, looping back to 0 when exceeds mag array length
    
        // Pick up the mag if it feels heavy (more than half full)
        if (float(DHWP.AmmoMags[i]) / float(MaxAmmo(0)) > 0.5)
        {
            PrimaryAmmoArray[PrimaryAmmoArray.Length] = DHWP.AmmoMags[i];
            DHWP.AmmoMags.Remove(i, 1);
            --i; // need to adjust for array member being removed, otherwise we'll skip the next mag
        }
    

    Broke it down into relevant psuedocode:

    i = 0
    
    while (mags not full & pickup has mags):
        i = ++i % pickup.mags.length
    
        if mag(i) not more than half full:
            add mag to weapon
            remove mag from pickup
            --i
    

    The problem arises when the player's weapon has a more room for additional magazines than the pickup has magazines that are more than half full. When this happens, the code will endlessly search for magazines that don't exist, resulting in this runaway loop.

    The offending code was committed in a60653e1 by @Matt_UK. Will sort out a fix for this.

  5. Log in to comment