Как сделать таблицу рекордов windows forms

Обновлено: 04.07.2024

День добрый.
Решил я заняться написанием сервиса онлайн таблиц рекордов для игроделов, да не простого, а с разными фишками.
Использую C++ в связке с php (cakephp пока что) с помощью libCURL.
Планирую сделать DLL и набор скриптов сперва для GameMaker, а затем, если покатит - и на другие движки, а ещё в дальнейшем и на другие платформы.
Мой вопрос тривиальный, и, наверное, этот вопрос многих уже достал: как обеспечить оптимальный уровень безопасности?
Под оптимальным уровенем безопасности понимаю защиту от фальсификации данных.

Если есть здесь народные умельцы, то просьба высказать свои соображения и советы как сделать. С радостью выслушаю
Ответы в духе "это лажа" или "делать нефиг?" или "всё равно не получиться" - не принимаются.
Так же не рассматриваю ответы в духе "да чё, берёшь методом POST фигачишь и не паришься"
Меня интересует более серьёзный подход, т.к. я надеюсь, что этот форум читают серёзные люди.

Итак, суть сервиса:
Помочь новчикам и проф разрабам легко внедрять в свои игры таблицы рекордов с несколькими типами рекордов для одной игры.
Регистрируешся, добавляешь игру, получаешь доступ к созданию типов рекордов, уровней, локаций и прочей фигней которая может понадобиться.
Игроки теперь смогут соревноваться не только по одному типу рекордов, но и по нескольким, т.е. игрок сможет быть самым быстрым, или самым коолекционером, и т.д. + Общий портал для игроков. На убийцу Стима или XBOX live не претендую, ибо суть моего проекта в таблицах рекордов а не в сервисе достижений.

На данный момент спроектирована база данных и готов каркас сайта (собствено cakephp)
Когда добрался до программирования передачи данных, решил что сперва узнаю как вообще это делается (несмотря на то что с сетью работал, программировал сокеты, писал сайты).

Пока что вижу два варианта:
1) Через сокеты, но тогда просьба помочь разобраться с тем как активировать сокеты на стороне php скрипта, т.е. как установить соединение с выполняющимся php скриптом? Со стороны С++ у меня проблем с сокетами нет.
2) Через libCURL. Вот тут то уже мне кое-что не нравится. А именно то, что параметры запроса отправляются методом POST. И ещё вопрос тем кто пользовал - насколько разумно использовать libCURL, учитывая что я буду делать как мнимум двойной запрос (запрос на подключение и отправка рекордов со стороны клиента, принятие запроса отправка ключа для проверки и проверка рекрдов с ключём со стороны сервера).

И ещё вопрос: чем посоветуете шифровать данные и какие библиотеки, функции(если вам не лень писать) использовать. Интересует шифрование данных со стороны С++ и со стороны PHP. Т.е. чтобы рекрод зашифрованный на стороне клиента мог быть однозначно расшифрован на стороне сервера. С шифрованием данных по сети ни разу дела не имел.

И возможен ли такой вариант и насколько он будет надёжен: если ключ шифрования известен только сверверу(и выдаётся разработчику игры) и только клиенту (вшит в игру разработчиком игры), а в сети передаются только шифрованные данные?

Или может быть есть какие-то готовые решения (аля libCURL) для передачи данных между С++ и PHP с поддержкой соединения, и сразу с шифрованием?

P.S. И не надо мне лечить тему, что проф разрабы сами напишут свои системы онлайн рекордов. Если проф разрабы были бы действительно проф - писали бы свои игры на ассемблере. Всегда проще использовать готовые проверенные решения, чем каждый раз изобретать велосипед самому.

100 % способа защиты не будет, т.к. здесь сервер вынужден доверять клиенту.
необходимо обезопасить сейвы игры, если они есть, от редактирования,
а также оперативную память игры, от тренеров.
т.к. если можно начитерить, то начитерят, и шифруй-не шифруй рекорды.

Если данная проблема решена.
Тогда можно отправлять по SSL сейв игры(либо выдержку из него, зависит от конкретного случая)
на сервере сейв обрабатывается и выкладывается в таблицу. Естественно, алгоритм должен загружаться на сервер разработчиком игры.

Либо считать на клиенте, но тогда нужна защита модуля подсчета от модификации. см Обфускаторы

Вообщем большую часть безопасности все равно делать разработчику игры.

SaintHeiser
> Когда добрался до программирования передачи данных, решил что сперва узнаю как
> вообще это делается (несмотря на то что с сетью работал, программировал сокеты,
> писал сайты).
в твоем случае действительно достаточно POST запроса по SSL, с каким-либо ключом идентификации, который придется защищать в коде клиента. см. Обфускаторы
Этот ключ регистрируется разработчиком для своей игры, и "авторизирует" саму игру

На 100% защиту я и не расчитываю, т.к. это нереально.
Моя задача - оптимально защитить канал передачи данных от фальсификации.
Сэйвы и прочие штуки остаются на разработчиков.
Тем более я особо и не припомню, чтобы игры с онлайн таблицами рекордов хранили рекорды у себя в сэйвах.

Ладно, фиг с ним. Интересует в таком случае SSL. Как я говорил ни разу с шифрованием не имел дела. Погуглил и понял что SSL - это нечто вроде схемы, протокол.
Я так понял, что ты предлагаешь ту же схему, что я писал в первом посте?

И возможен ли такой вариант и насколько он будет надёжен: если ключ шифрования известен только сверверу(и выдаётся разработчику игры) и только клиенту (вшит в игру разработчиком игры), а в сети передаются только шифрованные данные?

Если я не прав, не подскажешь возможные реализации в C++ и PHP, или предполагается, что я сам до этого допераю и реализовываю?
Про обфускаторы не знал, спасибо.

1. Сортируешь параметры запроса по алфавиту
2. Склеиваешь параметры в строку (gameID=5837&player=vasya&score=3434)
3. Приписываешь в конец строки секретный ключ, который выдаётся каждой игре (gameID=5837&player=vasya&score=34341bc29b36f623ba82aaf6724fd3b16718)
4. Считаешь md5 этой строки (получилось, например, c93d3bf7a7c4afe94b64e30c2ce39f4f)
5. Посылаешь запрос на сервер (score.php?gameID=5837&player=vasya&score=3434&sig=c93d3bf7a7c4afe94b64e30c2ce39f4f)
6. На сервере считаешь md5 параметров используя секретный ключ, так же как и на клиенте, и сравниваешь с параметром sig, если совпали значит запрос не поддельный.
.
7. PROFIT!!

Спасибо, теперь ясно. Но кое с чем не соглашусь:

6. На сервере считаешь md5 параметров используя секретный ключ, так же как и на клиенте, и сравниваешь с параметром sig, если совпали значит запрос не
А если мега злобный игрок узнал ключ и зашифровал запрос в md5 и отправил, рекорд зачтётся как правильный.

Я вот поэтому думаю сделать ещё дополнительное действие - сперва игра обращаетсяк серверу. Сервер заносит запрос с датой в с пециальную таблицу и выслыает проверочный код, который идёт в довесок к параметрам запроса. Игра получает этот код и отправляет параметр с довеском на сервер. Сервер получает код, смотрит время за которое ответ получен и если таймаут то ошибка, так же помечает в спец таблице запрос как удовлетворённый, поэтому если ещё раз придёт обращение скрипта то сервер узнает, что либо клиент стормозил либо пытается ещё раз подсунуть тот же рекорд.

Пока что думаю использовать для этого libCURL, раз вы считаете что POST будет достаточно.

В предыдущей статье мы внесли множество визуальных улучшений в наш SnakeWPF. Сейчас я хотел бы добавить крутую функцию A high score list! (Список рекордов). Кроме того, я бы хотел сделать игру более удобной путем добавления экрана приветствия. Также я заменю непривычное для игр всплывающее окно "You died" ("Вы умерли") на дополнительный игровой экран.

Нам понадобится достаточно много дополнительного кода, чтобы это сделать, но давайте начнем с простого - с XAML!

Первым делом я добавлю большой кусок XAML в окно Snake. Код в основном состоит из 4 новых контейнеров (в данном случае это Border controls), которые будут содержать набор дочерних элементов для поддержки различных сценариев:

Мы добавим эти контейнеры в GameArea Canvas и затем просто спрячем их до тех пор пока они не понадобятся. Как уже говорилось, каждый контейнер будет служить определенной цели и включать немного markup, но мы будем использовать только те элементы управления, которые уже обсуждались ранее.

Добавьте этот код XAML внутрь элемента управления GameArea Canvas:


Здесь коротко говорится, что это за игра, как управлять Змейкой и как начать игру. Border, где находится текст, видим с самого начала, это будет первое, что увидит игрок, когда игра начнется. Внизу экрана я добавил кнопку для показа списка рекордов (который мы добавим через минуту). Управление кликом (Click event handler) мы добавим позже в Code-behind.

Список рекордов

Ну а теперь займемся более сложной частью, потому что я хочу это сделать WPF-способом и использовать привязку данных (data binding) для отображения Списка рекордов вместо создания и обновления этого списка вручную. Но не волнуйтесь, я все объясню по пути. Первым делом, добавьте этот кусок XAML внутрь GameArea Canvas, точно так как мы делали это ранее - Canvas, как упоминалось ранее, будет содержать все наши элементы управления Border, каждый из которых имеет свою собственную функциональность для нашей игры:


Заметьте что первоначально Border не отображается (Visibility = Collapsed). Мы используем ItemsControl (о котором говорилось ранее), с пользовательским ItemsSource которое мы назвали HighScoreListViewSource. Мы будем использовать CollectionViewSource для того чтобы убедиться, что коллекция (collection), к которой мы привязываемся, была правильно отсортирована. Нам нужно определить этот ресурс в Window XAML, поэтому дабавьте этот фрагмент разметки как дочерний элемент тэга Window, чтобы Window выглядел вот таким образом:

Обратите внимание, что я добавил новую ссылку: xmlns:scm используемую для доступа к типу SortDescription. Также я добавил свойство x:Name и установил исходное значение window, чтобы мы могли ссылаться на составные определенные в классе MainWindow в Code-behind.

В Window.Resources я добавил CollectionViewSource, который использует привязку для присоединения к свойству HighscoreList, которое мы определим ниже. Также обратите внимание, что я добавляю SortDescription, указывая что список должен быть отсортирован по убыванию по свойству Score. Это означает, что первым будет показан наивысший счет.

В коде ниже мы должны определить свойство HighscoreList, от которого зависит ItemsSource, но мы вернемся к этому после того как мы закончим добавление последнего XAML.

Новый рекорд


Все делается просто, TextBox для ввода имени и кнопка Button, которую можно нажать и таким образом добавить имя в список. Позже мы добавим обработчик события (event handler) BtnAddToHighscoreList_Click.

"О нет - вы умерли!"

Последняя часть это экран "О нет, вы умерли и не попали в список рекордов", который мы используем вместо скучного MessageBox, который исполнял ту же функцию раньше. XAML код выглядит вот таким образом:


Этот экран сообщает о неудаче, показывает финальный счет и указывает, как начать игру заново - довольно просто!

Создаем список рекордов

Другой обработчик событий (event handler) нужен для того, чтобы добавлять новую запись в Список рекордов, но для этого нам нужно сделать пару добавлений. Первым делом, собственно свойство, которое будет сохранять рекорды:

Как видно, это ObservableCollection, содержит тип SnakeHighscore. Первым делом, включите пространство имен (namespace) содержащее тип ObservableCollection:

Достаточно простой класс, как вы видите - он служит в качестве контейнера для имени и счета игрока, который достиг списка рекордов.

Загружаем/сохраняем Список рекордов

Нам также нужно написать немного кода, чтобы загружать и сохранять список - метод Save будет вызываться когда новая запись будет записана в список, а метод Load будем вызывать в начале игрыю Я буду использовать простой XML файл для того, чтобы хранить данные для списка, это позволит нам использовать стандартный класс XmlSerializer, с помощью которого легко автоматически загружать и сохранять список.

Существует множество возможностей для загрузки/сохранения данных, и несколько подходящих форматов например JSON или простой текстовый файл (plain text file), но я хотел написать эту часть используя наименьшее количество кода, т.к. это не так важно для изучения WPF. Также, подход XmlSerializer делает код очень гибким - вы легко можете добавить новые свойства в класс SnakeHighScore и они будут автоматически сохранены. Вот мой метод LoadHighscoreList():

Для этого нужно включить в код пару новых пространств имен (namespaces):

Не забудьте вызвать метод LoadHighscoreList(), например в конструкторе Window:

Теперь создадим метод SaveHighscoreList():

Метод Save следует вызывать когда мы добавляем новую запись - это происходит в обработчике событий (event handler) BtnAddToHighscoreList_Click(), который должен выглядеть вот так:

Это достаточно просто: Мы должны решить нужно ли добавлять новую запись в топ списка (как новое лучшее достижение!) или ее стоит разместить ниже. Как только мы получаем новый индекс, мы создаем новый экземпляр класса SnakeHighscore, используя текущий счет и имя, введенное игроком. Затем мы удаляем все ненужные записи снизу списка, если список становится длиннее, чем мы хотим (MaxHighscoreListEntryCount). Затем мы сохраняем список (SaveHighscoreList()) и скрываем контейнер bdrNewHighscore, делая фокус на контейнер bdrHighscoreList.

Однако, остается еще кое-что, что нужно сдеать. Первым делом, эти новые экраны ("О нет, вы умерли" и "Список рекордов" и проч.) должны быть скрыты каждый раз когда начинается новая игра. Поэтому верхня часть метода StartNewGame(), который мы написали в прошлый раз, теперь должен выглядеть следующим образом:

Следующее, что мы должны сделать это изменить метод EndGame(). Вместо того, чтобы просто показывать MessageBox, мы должны проверить набрал ли игрок достаточно очков, чтобы быть добавленным в Список рекордов или нет. И затем показать соответствующий контейнер:

Главное, что делает этот метод - проверяет есть ли еще свободные места в Списке рекордов (мы определили, что максимально будет 5 записей) или возможно игрок побил один из существующих рекордов. Если так мы разрешаем игроку добавить свое имя с помощью контейнера bdrNewHighscore. Если нового рекорда нет вместо этого мы показываем контейнер bdrEndOfGame. Убедитесь, что константа MaxHighscoreListEntryCount определена.

Теперь, закончив все это, начните игру заново, выложитесь по максимуму - и как только игра закончится надеюсь увидите себя в новом списке рекордов Snake WPF!

Обобщая

В этой части мы внесли МНОГО изменений в разработку нашей игры SnakeWPF. Наиболее очевидное это конечно Список рекордов, который потребовал достаточно много добавления кода и XAML, но это того стоило! Вдобавок мы внесли несколько хороших улучшений юзабилити, что делает наш проект все более похожим на настоящую игру.

Списки инициализируются следующим образом:

Это та часть кода, где, если вы провалили игру, он сохраняет номер вашего игрока и счет, а затем открывает форму табло.

3 ответа

Я делаю игру snake для проекта для школы в python году. Я использую модуль pygame и закодировал всю игру, кроме таблицы рекордов! Крайний срок-завтра, и я начинаю терять надежду! В основном у меня есть все пользовательские данные, которые вводятся, нажимается имя пользователя, и оценка помещается.

Я делаю игру whack-a-mole в javascript, и мне нужно выяснить,как сделать таблицу рекордов. Я думал, что база данных HTML5 будет хорошо работать, но я не могу понять, как ее интегрировать. У меня есть счетчик, который подсчитывает количество успешных кликов по кротам. Мне нужно взять его значение и.

В идеале вы хотели бы создать объект, назовем его PlayerScore, который содержал бы как номер игрока, так и счет.

Затем вы можете отсортировать список PlayerScores по счету, и идентификатор игрока все равно будет иметь эту связь с отсортированным списком очков.

Если я вас правильно понял, проблема, с которой вы столкнулись, находится в части "sorting". Вы можете легко отсортировать это, используя linq.

Допустим, у вас есть коллекция с именем "PlayerScores" со всеми парами игрок/счет, как сказал Джошуа (или словарь, если хотите, он может работать и здесь), тогда вы можете сделать что-то вроде:

Кроме того, если вы предпочитаете работать с массивом, вы связываете это с ToArray():

Вы можете улучшить код таблицы лидеров, используя цикл и находя элементы по идентификатору, как показано ниже. Возможно, вам придется изменить элементы управления на контейнер, в котором размещены ваши текстовые поля.

Похожие вопросы:

У меня есть таблица, в которой хранятся рекорды для игры. Эта игра имеет много уровней, где баллы затем упорядочиваются по баллу DESC (который является индексом), где уровень является уровнем ID.

Я делаю игру snake для проекта для школы в python году. Я использую модуль pygame и закодировал всю игру, кроме таблицы рекордов! Крайний срок-завтра, и я начинаю терять надежду! В основном у меня.

Я делаю игру whack-a-mole в javascript, и мне нужно выяснить,как сделать таблицу рекордов. Я думал, что база данных HTML5 будет хорошо работать, но я не могу понять, как ее интегрировать. У меня.

Я пытаюсь написать программу, которая использует глобальный вектор структуры в форме c++ windows. Ниже приведен код. Комментируемые области-это попытки, которые я сделал, чтобы создать вектор.

Я делаю игру, в которой цель состоит в том, чтобы каждый раз получать лучший высокий балл. Когда игра закончится, пользователю будет направлена таблица рекордов. Вместо таблицы высоких баллов.

Несколько месяцев назад я создал приложение для телефона Windows и теперь хочу сделать его и для магазина Windows. У меня все работает, кроме сохранения рекордов. Я пробовал читать APIs, но по.

Читайте также: