Esempio n. 1
0
        /// <summary>Unalias some Cards, e.g. before a shuffle</summary>
        /// <param name="card">An array containing the Card ids to unalias.</param>
        /// <param name="type">An array containing the corresponding revealed CardIdentity ids.</param>
        public void Unalias(int[] card, ulong[] type)
        {
            if (card.Length != type.Length)
            {
                Program.TraceWarning("[Unalias] Card and type lengths don't match."); return;
            }
            Pile         g     = null;
            List <int>   cards = new List <int>(card.Length);
            List <ulong> types = new List <ulong>(card.Length);

            for (int i = 0; i < card.Length; i++)
            {
                Card c = Card.Find(card[i]);
                if (c == null)
                {
                    Program.TraceWarning("[Unalias] Card not found."); continue;
                }
                if (g == null)
                {
                    g = c.Group as Pile;
                }
                else if (g != c.Group)
                {
                    Program.TraceWarning("[Unalias] Not all cards belong to the same group!"); continue;
                }
                // Check nobody cheated
                if (!c.Type.MySecret)
                {
                    if (c.Type.Key != Crypto.ModExp(type[i]))
                    {
                        Program.TraceWarning("[Unalias] Card identity doesn't match.");
                    }
                }
                // Substitue the card's identity
                CardIdentity ci = CardIdentity.Find((int)type[i]);
                if (ci == null)
                {
                    Program.TraceWarning("[Unalias] Card identity not found."); continue;
                }
                CardIdentity.Delete(c.Type.Id); c.Type = ci;
                // Propagate unaliasing
                if (ci.Alias && ci.MySecret)
                {
                    cards.Add(c.Id);
                }
                types.Add(ci.Key);
            }
            if (cards.Count > 0)
            {
                Program.Client.Rpc.Unalias(cards.ToArray(), types.ToArray());
            }
            if (g == null)
            {
                return;
            }
            if (!g.PreparingShuffle)
            {
                Program.TraceWarning("[Unalias] Cards revealed are not in a group prepared for shuffle."); return;
            }
            // If all cards are now revealed, one can proceed to shuffling
            if (!g.WantToShuffle)
            {
                return;
            }
            bool done = false;

            for (int i = 0; !done && i < g.Count; i++)
            {
                done = g[i].Type.Alias;
            }
            if (!done)
            {
                g.DoShuffle();
            }
        }
Esempio n. 2
0
        /// <summary>Reveal one card's identity</summary>
        /// <param name="card">The card, whose identity is revealed</param>
        /// <param name="revealed">Either the salted CardIdentity id (in the case of an alias), or the salted, condensed Card GUID.</param>
        /// <param name="guid"> </param>
        public void Reveal(Card card, ulong revealed, Guid guid)
        {
            // Save old id
            CardIdentity oldType = card.Type;

            // Check if the card is rightfully revealed
            if (!card.Type.Revealing)
            {
                Program.Trace.TraceEvent(TraceEventType.Warning, EventIds.Event, "Someone tries to reveal a card which is not visible to everybody.");
            }
            // Check if we can trust other clients
            if (!card.Type.MySecret)
            {
                if (guid != Guid.Empty && (uint)revealed != guid.Condense())
                {
                    Program.Trace.TraceEvent(TraceEventType.Warning, EventIds.Event, "[Reveal] Alias and id aren't the same. One client is buggy or tries to cheat.");
                }
                if (Crypto.ModExp(revealed) != card.Type.Key)
                {
                    Program.Trace.TraceEvent(TraceEventType.Warning, EventIds.Event, "[Reveal] Card identity doesn't match. One client is buggy or tries to cheat.");
                }
            }
            else
            {
                card.Type.MySecret = false;
            }
            // Reveal an alias
            if (guid == Guid.Empty)
            {
                // Find the new type
                CardIdentity newId = CardIdentity.Find((int)revealed);
                // HACK: it is unclear to me how the CardIdentity could not be found and newId ends up null
                // see this bug report: https://octgn.16bugs.com/projects/3602/bugs/192070
                // for now I'm just doing nothing (supposing that it means the type was already revealed).
                if (newId == null)
                {
                    card.Reveal(); return;
                }
                // Possibly copy the model, if it was known and isn't anymore
                // (possible when the alias has beeen locally revealed)
                if (newId.Model == null)
                {
                    newId.Model = card.Type.Model;
                }
                // Set the new type
                card.Type = newId;
                // Delete the old identity
                CardIdentity.Delete(oldType.Id);
                // Possibly reveal the alias further
                card.Reveal();
                // Raise a notification
                oldType.OnRevealed(newId);
            }
            // Reveal a card's type
            else if (card.Type.Model == null)
            {
                card.SetModel(Program.GameEngine.Definition.GetCardById(guid));
                // Raise a notification
                oldType.OnRevealed(oldType);
            }
        }