using System; using System.Collections.Generic; using System.Linq; using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace Pokemon_Drinking_Game { /// /// Interaction logic for MainWindow.xaml /// public partial class MainWindow : Window { BitmapImage subImage; List players; int ourPlayerIndex; int currentTurn; Timer updateTimer; TcpClient client; public MainWindow() { InitializeComponent(); // Load the sub image just once loadImage(); players = new List(); //TcpClient client = new TcpClient("pdgserver.kauripeak.co.nz", 13000); } void loadImage() { subImage = new(new Uri("pack://application:,,,/pokemon_v3.png")); int i = 0; } private void buttons_MouseEnter(object sender, MouseEventArgs e) { // Replace center image zoomPieceImage.Source = retrieveSubImage(subImage, (Button)sender); zoomPieceImage.Visibility = Visibility.Visible; } private void buttons_MouseLeave(object sender, MouseEventArgs e) { // Hide center image //zoomPieceImage.Source = new BitmapImage(); zoomPieceImage.Visibility = Visibility.Collapsed; } CroppedBitmap retrieveSubImage(BitmapImage source, Button button) { // Get various element heights & widths int imageWidth = source.PixelWidth; int imageHight = source.PixelHeight; int pixPerTile = imageWidth / 9 -1; double parentHeight = ((Grid)button.Parent).ActualHeight; double parentWidth = ((Grid)button.Parent).ActualWidth; int row = -1; int col = -1; // Hard coding cause its a bitch if (button == palletTownButton) { col = 0; row = 8; } else if (button == rattataButton) { col = 0; row = 7; } else if (button == pidgeyButton) { col = 0; row = 6; } else if (button == caterpieButton) { col = 0; row = 5; } else if (button == pikachuButton) { col = 0; row = 4; } else if (button == beedrilButton) { col = 0; row = 3; } else if (button == pewterButton) { col = 0; row = 2; } else if (button == nidoranButton) { col = 0; row = 1; } else if (button == zubatButton) { col = 0; row = 0; } // else if (button == clefairyButton) { col = 1; row = 0; } else if (button == jigglypuffButton) { col = 2; row = 0; } else if (button == abraButton) { col = 3; row = 0; } else if (button == garyButton) { col = 4; row = 0; } else if (button == ceruleanButton) { col = 5; row = 0; } else if (button == slowpokeButton) { col = 6; row = 0; } else if (button == bellsproutButton) { col = 7; row = 0; } else if (button == meowthButton) { col = 8; row = 0; } // else if (button == diglettButton) { col = 8; row = 1; } else if (button == ssanneButton) { col = 8; row = 2; } else if (button == vermillionButton) { col = 8; row = 3; } else if (button == bicycleButton) { col = 8; row = 4; } else if (button == magikarpButton) { col = 8; row = 5; } else if (button == sandshrewButton) { col = 8; row = 6; } else if (button == pokemontowerButton) { col = 8; row = 7; } else if (button == channelerButton) { col = 8; row = 8; } // else if (button == haunterButton) { col = 7; row = 8; } else if (button == cuboneButton) { col = 6; row = 8; } else if (button == ghostButton) { col = 5; row = 8; } else if (button == abra2Button) { col = 4; row = 8; } else if (button == snorlaxButton) { col = 3; row = 8; } else if (button == gary2Button) { col = 2; row = 8; } else if (button == eeveeButton) { col = 1; row = 8; } // else if (button == celadonButton) { col = 1; row = 7; } else if (button == psyduckButton) { col = 1; row = 6; } else if (button == evolutionButton) { col = 1; row = 5; } else if (button == porygonButton) { col = 1; row = 4; } else if (button == silphButton) { col = 1; row = 3; } else if (button == scientistButton) { col = 1; row = 2; } else if (button == laprasButton) { col = 1; row = 1; } // else if (button == rocketButton) { col = 2; row = 1; } else if (button == giovanniButton) { col = 3; row = 1; } else if (button == rarecandyButton) { col = 4; row = 1; } else if (button == gary3Button) { col = 5; row = 1; } else if (button == saffronButton) { col = 6; row = 1; } else if (button == hitmonsButton) { col = 7; row = 1; } // else if (button == krabbyButton) { col = 7; row = 2; } else if (button == dittoButton) { col = 7; row = 3; } else if (button == doduoButton) { col = 7; row = 4; } else if (button == safariButton) { col = 7; row = 5; } else if (button == dratiniButton) { col = 7; row = 6; } else if (button == taurosButton) { col = 7; row = 7; } // else if (button == chanseyButton) { col = 6; row = 7; } else if (button == fuchsiaButton) { col = 5; row = 7; } else if (button == electrodeButton) { col = 4; row = 7; } else if (button == electabuzzButton) { col = 3; row = 7; } else if (button == poliwagButton) { col = 2; row = 7; } // else if (button == seakingButton) { col = 2; row = 6; } else if (button == missingnoButton) { col = 2; row = 5; } else if (button == cinnabarButton) { col = 2; row = 4; } else if (button == koffingButton) { col = 2; row = 3; } else if (button == fossilButton) { col = 2; row = 2; } // else if (button == pokeballButton) { col = 3; row = 2; } else if (button == persianButton) { col = 4; row = 2; } else if (button == viridianButton) { col = 5; row = 2; } else if (button == fearowButton) { col = 6; row = 2; } // else if (button == gravellerButton) { col = 6; row = 3; } else if (button == gyradosButton) { col = 6; row = 4; } else if (button == dragoniteButton) { col = 6; row = 5; } else if (button == legendbirdButton) { col = 6; row = 6; } // else if (button == elitefourButton) { col = 5; row = 6; } else if (button == championButton) { col = 4; row = 6; } else if (button == masterButton) { col = 3; row = 6; } Int32Rect pixelRect = new Int32Rect(pixPerTile * col, pixPerTile * row , pixPerTile, pixPerTile); CroppedBitmap cb = new CroppedBitmap(source, pixelRect); return cb; } byte[] overflowBuffer; /// /// Server logic /// Called periodically (e.g. 1/10 of a second), retrieves new data from the buffer, and /// sends out any updates that have occured. /// /// Data packets are 0xFF terminated (new command is the proceeding byte) /// Data terminations are 0xFE (next data type is the proceeding byte; does not apply to deterministic primative sizes) /// strings are expected to be sent in UTF-8 format /// /// As this is all in TCP, data is guaranteed to be in the correct order /// void ClientUpdate() { // *************************** // **** Ensure connected *** // *************************** if (!client.Connected) { } // *************************** // ****** Recieve Data ***** // *************************** if (client.Available > 0) { int available = client.Available; // Internal byte array to store all awaiting bytes byte[] buffer = new byte[available]; // Get the underlying networkstream, to read and write NetworkStream connectionStream = client.GetStream(); connectionStream.Read(buffer, 0, available); int pos = 0; while (pos < available) { int command = buffer[pos] >> 4; // Get the four command bits ourPlayerIndex = buffer[pos++] & 0xF; // Ensure we are the correct indexed player switch (command) // post-increment past the command byte { case 0: // Server queries a heartbeat response connectionStream.Write(new byte[] { (byte)ourPlayerIndex, 1, 0xFF }); break; case 1: // Server has a board (game) update while (buffer[pos] != 0xFF) { // First four bits, after the command is the number of players int playerCount = buffer[pos] >> 4; // Next four are the number of players currentTurn = buffer[pos++] | 0xF; // Next // If there is a different number of players, create a new list of players if (players.Count != playerCount) { players = new List(playerCount); } // Next bit is a flag, denoting if the current player is a } break; default: break; } } UpdateUI(); } // *************************** // ******* Send Data ******* // *************************** } void UpdateUI() { Brush labelBrush = new SolidColorBrush(Color.FromRgb(255, 255, 255)); Application.Current.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Render, new Action(() => { PlayerList.Children.Clear(); // do UI updates here foreach (var item in players) { Label playerLabel = new Label() { Content = item.name, Foreground = labelBrush }; PlayerList.Children.Add(playerLabel); } })); } private void ConnectButton_Click(object sender, RoutedEventArgs e) { // Do connection using props if (client != null) { client.Close(); } bool success = false; try { client = new TcpClient(AddressTextBox.Text, Convert.ToInt32(PortTextBox.Text)); success = true; } catch (Exception ex) { Console.WriteLine(ex); } if (success) { ConnectionGrid.Visibility = Visibility.Collapsed; GameGrid.Visibility = Visibility.Visible; ourPlayerIndex = 0; currentTurn = 0; List sendBytes = new(); sendBytes.Add(1 << 4); sendBytes.AddRange(Encoding.UTF8.GetBytes(PlayerNameTextBox.Text)); sendBytes.Add(0xFF); // Send through the player name client.GetStream().Write(sendBytes.ToArray()); // Add listener for data updateTimer = new Timer((t) => { ClientUpdate(); }); updateTimer.Change(100, 33); } } } struct Player { public string name; public int row; public int column; public long lastTime; public Player(string name, int row, int column) { this.name = name; this.row = row; this.column = column; this.lastTime = DateTime.Now.Ticks; } public override string ToString() { return name + " (" + column + ", " + row + ")"; } } }