Изначально в наличии были четыре человека, серверная часть, немного наличных денег и абстрактный план в голове. Опыта разработки, на платформе Windows 8, ни у кого из нас не было, поэтому мы спешно читали литературу на тему: Windows 8, C#, .Net. Через два дня мы были готовы начать разработку, получив достаточно информации о структуре Metro приложений, сказался общий опыт работы с .NET. Далее двое начали заниматься прототипированием и экспериментами с платформой, что в будущем дало нужные ответы в максимально сжатые сроки. Параллельно составлялся первый календарный план работ, а последний человек постоянно искал дизайнера, который мог бы взяться за работу вместе с нами. Все продолжалось около 13-15 дней, за это время совместно оценивали присланные наброски частей игры, каждый набросок старались адекватно, с нашей точки зрения, оплатить. Дизайнер же сам выбирал, что он может и за какой срок нам представить, для этого у него в распоряжении была игра, использовавшая в своей основе HTML и JS. Стоимость набросков варьировалась от 1000 до 2000 рублей, в общей сложности рассмотрели 4 наброска. В итоге выбрали макет, получили время в 2 месяца на создание всего и стоимость примерно в 40 000 рублей за весь дизайн. Стоить отметить, что были претенденты с ценами от 100 000 рублей, что нас не устраивало. Далее, по составленному ТЗ, дизайнер присылал элементы, а мы решали подходят они или нет. Каждый элемент был разрезан на кусочки и подогнан в XAML разметке разработчиками, дизайнер использовал только графический редактор, не трогая Blend.
Серверная часть состоит из набора WCF сервисов, использующих привязку wsHttpBinding. Сервисы развернуты на базе Windows Service в среде Windows 2008 R2. Поскольку ранее использовался клиент на HTML, то все вопросы с аутентификацией и авторизацией решало MVC .NET приложение, а сервис принимал его как доверительное. Здесь же использование такого подхода было лишним и сложным так, как Metro приложения умеют взаимодействовать с WCF сервисами напрямую, хотя требуют использование сертификатов и basicHttpBinding. Тестовый сертификат был успешно установлен на машинах разработчиков и привязан к порту, использовавшемуся WCF, а так же получен реальный сертификат для публикации. Получилась такая инструкция для разработчиков:
- Получите сертификат и импортируете его;
- Запустите cmd и просмотрите порты с назначенными сертификатами: netsh http show sslcert, проверте, что на нужных адресах не указан сертификат до нас, нам нужен порт 8734 т.е. записи: 0.0.0.0:8734;
- Добавьте запись с параметрами сертификата, импортированного на первом шаге: netsh http add sslcert ipport=0.0.0.0:8734 certhash=ЗначениеХешаСертификата appid={GUID}. Значение хеш тега берется из поля «Отпечаток» сертификата на закладке «Состав», вводится без пробелов. Далее необходимо проверить наличие записи, повторив второй пункт.
Проблема аутентификации была решена реализацией наследника от UserNamePasswordValidator и использованием Windows Live ID. Полученный валидатор был добавлен в app.config сервисов.
<behaviors> <serviceBehaviors> <behavior name="Security"> <serviceCredentials> <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="Thisislogic.XGame.Service.Common.SecurityManager, Thisislogic.XGame.Service.Common" /> </serviceCredentials> </behavior> </serviceBehaviors> </behaviors>
В валидаторе разбирается, с использованием секретного ключа сервиса Live ID, пользовательский идентификатор и дается заключение, разрешено использование сервиса или нет.
public class SecurityValidator : UserNamePasswordValidator { private const string LiveSecretClientKey = "My_Secret_Key"; public override void Validate(string userName, string password) { try { if (string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(password)) { throw new Exception("User or Password not set"); } var d = new Dictionary<int, string>(); d.Add(0, LiveSecretClientKey); var jwt = new JsonWebToken(password, d); var jwtUserName = jwt.Claims.UserId; if (jwtUserName != userName) { throw new Exception("Manipulated Username"); } } catch (Exception e) { var fe = new FaultException("Unknown Username or Incorrect Password \n" + e.ToString()); throw fe; } } }
Позже была добавлена и аутентификация на основе уникального идентификатора пользователя, без участия Live ID. Ниже показан один из вариантов получения уникального идентификатора пользователя.
private string GetHardwareId() { var token = HardwareIdentification.GetPackageSpecificToken(null); var hardwareId = token.Id; var dataReader = DataReader.FromBuffer(hardwareId); var bytes = new byte[hardwareId.Length]; dataReader.ReadBytes(bytes); return BitConverter.ToString(bytes); }
К моменту согласования дизайнера, плану использования сервисов, окончанию прототипирования созрела декомпозиция работ и примерные сроки, многие из которых после неоднократно пересматривались. План был составлен с использованием MS Project и подсистемы Work Items в TFS 2010. Все задачи были распределены на TFS, в конце каждого рабочего дня получали обновления из TFS в план и смотрели, что и как следует поменять.
В качестве общей точки взаимодействия кода, документов и задач мы использовали TFS. Какие-то обсуждения проходили в Skype, но большая часть проведена лично. Код писался вместе двумя и более разработчиками, что позволило быстро распространить новый для нас подход MVVM, с одинаковым пониманием. Тут нам очень помог плагин Kind of Magic, позволивший не писать тонны кода с INotifyPropertyChanged.
[MagicAttribute] public abstract class PropertyChangedBase : INotifyPropertyChanged { protected virtual void RaisePropertyChanged(string propName) { var e = PropertyChanged; if (e != null) { SmartDispatcher.BeginInvoke(() => e(this, new PropertyChangedEventArgs(propName))); } } [MethodImpl(MethodImplOptions.NoInlining)] protected static void Raise() { } public event PropertyChangedEventHandler PropertyChanged; }
Архитектура приложения, в основном, зависела от того, что серверная часть уже есть. Все сводилось к тому, что процесс игры полностью происходит на сервере, клиент лишь, с определенным интервалом, запрашивает данные с сервера и обрабатывает их, отправляя ответы. Была принята терминология событий: серверных и клиентских, при этом сервер никогда не обращается к клиентам, привязка basicHttpBinding не подразумевает дуплекса. Работа с XAML частично была знакома по Silverlight и WPF технологиям, но все же основной опыт работы был с Windows Forms и ASP MVC. На работу с кодом и адаптацию дизайна было потрачено основное время, около 2 месяцев. Написание кода и сопутствующие вопросы ничем особым не отличались от других проектов, рассказывать о привязках, валидации, async-await не имеет смысла. После окончания разработки мы опубликовали в Windows Store игру.
В итоге сводная таблица результатов:
Деятельность | Время | Деньги |
---|---|---|
Обучение | 7 дней | 10000 |
Аренда помещения и технические расходы | 3 месяца | 35000 |
Дизайн | 3 месяца | 40000 |
Начальные эскизы | 15 дней | 6500 |
Зарплата | 2 месяца | 50000 |
Итого | 141500 |
Всего затрачено около 141500 рублей и 3 месяца работы.
ссылка на оригинал статьи http://habrahabr.ru/post/197104/
Добавить комментарий