Opening spawned shopfront bug

Hi there,
I've successfully spawned in a shopfront, and I'm trying to automatically open it for two players (vendor and customer).

I've attempted to achieve this by replicating the code for ShopFront's implementation of PlayerOpenLoot, since the virtual override will automatically pass true for positionChecks, and I want the two players to open the shop front from anywhere in the world.

What I get is both players opening the shop front, and both players can add/remove items from their respective containers, but the shop front controls and the vendor/customer names do not appear.

xTr3J54gXN5m2kV.png

        private static bool PlayerOpenShopFront(BasePlayer player, ShopFront shopFront)
        {
            StorageContainer container = shopFront;
            bool flag = player.inventory.loot.StartLootingEntity(container, false);
            if (flag)
            {
                BaseEntity ent = container;
                if (ent == null) return false;
                ent.SetFlag(BaseEntity.Flags.Open, true, false, true);
                container.AddContainers(player.inventory.loot);
                player.inventory.loot.SendImmediate();
                player.ClientRPCPlayer(null, player, "RPC_OpenLootPanel", container.panelName);
                ent.SendNetworkUpdate(BasePlayer.NetworkQueue.Update);
                player.inventory.loot.AddContainer(shopFront.customerInventory);
                player.inventory.loot.SendImmediate();
            }
            return flag;
        }
        // This is basically a torn apart implementation of the ShopFront class's PlayerOpenLoot function
        private static bool OpenShopFront(BasePlayer vendorPlayer, BasePlayer customerPlayer, ShopFront shopFront)
        {
            if (vendorPlayer == null || !IsPlayerValid(vendorPlayer.IPlayer) || customerPlayer == null || !IsPlayerValid(customerPlayer.IPlayer) 
                || shopFront == null || !shopFront.IsValid() || shopFront.IsDestroyed || shopFront.vendorPlayer != null || shopFront.customerPlayer != null) return false;
            if (!PlayerOpenShopFront(vendorPlayer, shopFront))
            {
                return false;
            }
            if (!PlayerOpenShopFront(customerPlayer, shopFront))
            {
                return false;
            }
            shopFront.vendorPlayer = vendorPlayer;
            shopFront.customerPlayer = customerPlayer;
            shopFront.ResetTrade();
            shopFront.UpdatePlayers();
            return true;
        }
        private ShopFront NewTradeShopFront()
        {
            ShopFront shopFront = GameManager.server.CreateEntity(SHOPFRONT_PREFAB) as ShopFront;
            if (shopFront == null) return null;
            shopFront.Spawn();
            return shopFront;
        }​

bump - anybody have any ideas?  been stuck with this for a while now...

try

front.globalBroadcast = true;
front.enableSaving = false;
front.Spawn();
​

Also add 1 second delay after spawning shop front

Enabling global broadcast worked, sort of.  I was confused at first because it was only showing my name in the shopfront window, but then I realized that both players need to be networked.  I don't exactly know how to do that but maybe it's...

vendorPlayer.net.group.AddSubscriber(customerPlayer.Connection);
customerPlayer.net.group.AddSubscriber(vendorPlayer.Connection);​

The other problem is that the accept button does not work 😬.  Working on it.

Edit: I think the reason accept button doesn't work is the following...
// ShopFront
// Token: 0x06001614 RID: 5652 RVA: 0x000867DC File Offset: 0x000849DC
[global::BaseEntity.RPC_Server]
[global::BaseEntity.RPC_Server.IsVisible(3f)]
public void AcceptClicked(global::BaseEntity.RPCMessage msg)​

And testing the OnShopAcceptClick hook confirms it's never called.  Not sure how that syntax works honestly - it must do a visibility/distance check on the player clicking the accept button??  🤷‍♂️

You don't need to network players

If the players are not networked, it says "No one" for the name of the player.  The other player can add and remove items, but the shop front does not think there are two people trading.  This also means the shopfront controls (accept button) are not displayed making trading impossible.

If the two players are trading near eachother, everything works.  I tried doing AddSubscriber and SendNetworkUpdate for each player but it didn't fix it.

Doing the following did work.  Although, I'm not sure what the consequences of this would be, or if it's even really a "correct" solution.

inviterPlayer.SendAsSnapshot(inviteePlayer.Connection);
inviteePlayer.SendAsSnapshot(inviterPlayer.Connection);
inviterPlayer.SendNetworkUpdate(BasePlayer.NetworkQueue.Update);
inviteePlayer.SendNetworkUpdate(BasePlayer.NetworkQueue.Update);
oDHqff8dgCYLxFO.jpg lolman300

If the players are not networked, it says "No one" for the name of the player.  The other player can add and remove items, but the shop front does not think there are two people trading.  This also means the shopfront controls (accept button) are not displayed making trading impossible.

If the two players are trading near eachother, everything works.  I tried doing AddSubscriber and SendNetworkUpdate for each player but it didn't fix it.

Doing the following did work.  Although, I'm not sure what the consequences of this would be, or if it's even really a "correct" solution.

inviterPlayer.SendAsSnapshot(inviteePlayer.Connection);
inviteePlayer.SendAsSnapshot(inviterPlayer.Connection);
inviterPlayer.SendNetworkUpdate(BasePlayer.NetworkQueue.Update);
inviteePlayer.SendNetworkUpdate(BasePlayer.NetworkQueue.Update);

Thats the only solution. I made it exactly like that

dNpkqFyTbVbWbfa.png Orange

Thats the only solution. I made it exactly like that

Well that's good to hear.

And for anyone who might stumble upon this thread looking for answers, here's everything I had to do (in addition to the posted code above) to handle spawning a shop front and opening it for two players.
  1. shopFront.globalBroadcast = true;
  2. Delay opening the shop front after spawning
  3. Handle OnEntityVisibilityCheck hook (undocumented, in BaseEntity->RPC_Server->IsVisible->Test(uint, string, BaseEntity, BasePlayer, float):bool
    1. object OnEntityVisibilityCheck(BaseEntity ent, BasePlayer player, uint id, string debugName, float maximumDistance)
              {
                  if (!(ent as ShopFront)) return null;
                  if (!_tradeSessionCache.ContainsKey(player.IPlayer)) return null;
                  return true;
              }
  4. Send both players a snapshot of their connection
    1. inviterPlayer.SendAsSnapshot(inviteePlayer.Connection);
      inviteePlayer.SendAsSnapshot(inviterPlayer.Connection);
      inviterPlayer.SendNetworkUpdate(BasePlayer.NetworkQueue.Update);
      inviteePlayer.SendNetworkUpdate(BasePlayer.NetworkQueue.Update);
oDHqff8dgCYLxFO.jpg lolman300
Well that's good to hear.

And for anyone who might stumble upon this thread looking for answers, here's everything I had to do (in addition to the posted code above) to handle spawning a shop front and opening it for two players.
  1. shopFront.globalBroadcast = true;
  2. Delay opening the shop front after spawning
  3. Handle OnEntityVisibilityCheck hook (undocumented, in BaseEntity->RPC_Server->IsVisible->Test(uint, string, BaseEntity, BasePlayer, float):bool
    1. object OnEntityVisibilityCheck(BaseEntity ent, BasePlayer player, uint id, string debugName, float maximumDistance)
              {
                  if (!(ent as ShopFront)) return null;
                  if (!_tradeSessionCache.ContainsKey(player.IPlayer)) return null;
                  return true;
              }
  4. Send both players a snapshot of their connection
    1. inviterPlayer.SendAsSnapshot(inviteePlayer.Connection);
      inviteePlayer.SendAsSnapshot(inviterPlayer.Connection);
      inviterPlayer.SendNetworkUpdate(BasePlayer.NetworkQueue.Update);
      inviteePlayer.SendNetworkUpdate(BasePlayer.NetworkQueue.Update);

Revealing all my secrets :P

dNpkqFyTbVbWbfa.png Orange

Revealing all my secrets :P


😅😅😅