Exemplo n.º 1
0
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            mws = new MainWindowSettings();

            if (pstatus.IsFirst)
            {
                if (!File.Exists(lisenceTextFilePath))
                    throw new FileNotFoundException("fatal:lisence_text_not_found");

                LisenceWindow lw = new LisenceWindow(File.ReadAllText(lisenceTextFilePath));
                lw.Owner = this;
                if (lw.ShowDialog() == false)
                {
                    Close();
                    return;
                }

                pstatus.IsFirst = false;
            }

            string wallpaperFileName = "/back.png";

            WebResourceHome webResourceHome = new WebResourceHome(mws.IsDefaultUi, "CREA2014.WebResources.home2.htm", Path.Combine(mws.UiFilesDirectory, "home2.htm"), entryAssembly);
            webResourceHome.port = (ushort)mws.PortWebSocket;

            Dictionary<string, WebResourceBase> resources = new Dictionary<string, WebResourceBase>();
            resources.Add(wallpaperFileName, new WebResourceWallpaper(mws.IsWallpaper ? mws.Wallpaper : null, mws.WallpaperOpacity));
            resources.Add("/favicon.ico", new WebResourceEmbedded("CREA2014.up0669_2.ico", entryAssembly));
            resources.Add("/knockout-3.2.0.js", new WebResourceEmbedded("CREA2014.WebResources.knockout-3.2.0.js", entryAssembly));
            resources.Add("/jquery-2.1.1.js", new WebResourceEmbedded("CREA2014.WebResources.jquery-2.1.1.js", entryAssembly));
            resources.Add("/jquery-ui-1.10.4.custom.js", new WebResourceEmbedded("CREA2014.WebResources.jquery-ui-1.10.4.custom.js", entryAssembly));
            resources.Add("/", webResourceHome);

            _CreateUiFiles = (basePath) =>
            {
                foreach (var path in new string[] { "CREA2014.WebResources.home2.htm" })
                {
                    string fullPath = Path.Combine(basePath, path);
                    if (File.Exists(fullPath))
                        File.Move(fullPath, fullPath + DateTime.Now.Ticks.ToString());
                    using (Stream stream = entryAssembly.GetManifestResourceStream(path))
                    {
                        byte[] data = new byte[stream.Length];
                        stream.Read(data, 0, data.Length);
                        File.WriteAllText(fullPath, Encoding.UTF8.GetString(data));
                    }
                }
            };

            bool isStartedWebServer = false;
            Action _StartWebServer = () =>
            {
                if (!HttpListener.IsSupported)
                    throw new Exception("fatal:http_listener_not_supported");

                DefaltNetworkInterface defaultNetworkInterface = new DefaltNetworkInterface();
                defaultNetworkInterface.Get();

                HttpListener innerHl = hl = new HttpListener();
                innerHl.Prefixes.Add("http://*:" + mws.PortWebServer.ToString() + "/");
                try
                {
                    innerHl.Start();
                }
                catch (HttpListenerException ex)
                {
                    if (ex.ErrorCode == 183)
                    {
                        MessageBox.Show("既にポート番号が使用されているため内部Webサーバを起動できませんでした。".Multilanguage(214));

                        return;
                    }
                    else if (ex.ErrorCode == 5)
                        throw new HttpListenerException(ex.ErrorCode, "fatal:require_administrator");

                    throw ex;
                }

                isStartedWebServer = true;

                Thread thread = new Thread(() =>
                {
                    while (true)
                    {
                        HttpListenerContext hlc = null;

                        try
                        {
                            hlc = innerHl.GetContext();
                        }
                        catch (HttpListenerException)
                        {
                            innerHl.Close();
                            break;
                        }

                        using (HttpListenerResponse hlres = hlc.Response)
                            if (resources.Keys.Contains(hlc.Request.RawUrl))
                            {
                                bool isLocalhost = hlc.Request.RemoteEndPoint.Address.Equals(IPAddress.Loopback) || hlc.Request.RemoteEndPoint.Address.Equals(IPAddress.IPv6Loopback);

                                if (!mws.IsWebServerAcceptExternal && !isLocalhost)
                                    continue;

                                byte[] data = null;
                                if (hlc.Request.RawUrl == "/")
                                {
                                    hlres.StatusCode = (int)HttpStatusCode.OK;
                                    hlres.ContentType = MediaTypeNames.Text.Html;
                                    hlres.ContentEncoding = Encoding.UTF8;

                                    WebResourceHome wrh = resources[hlc.Request.RawUrl] as WebResourceHome;
                                    wrh.host = isLocalhost ? "localhost" : defaultNetworkInterface.MachineIpAddress.ToString();

                                    data = wrh.GetData();
                                }
                                else
                                    data = resources[hlc.Request.RawUrl].GetData();

                                hlres.OutputStream.Write(data, 0, data.Length);
                            }
                            else
                                this.RaiseError("web_server_data", 5);
                    }
                });
                thread.Start();
            };
            _StartWebServer();

            bool flag = false;

            //<未改良>WebSocketListenerを使用する
            //<未実装>localhost以外からの接続をはじく
            //<未実装>既にポートが使用されている場合
            SessionHandler<WebSocketSession, string> newMessageReceived = (session, message) =>
            {
                //2014/08/26
                //このイベントハンドラの中で例外が発生しても、例外を捕捉していないにも拘らず、
                //捕捉されなかった例外とならない
                //内部で例外が握り潰されているのではないかと思うが・・・
                //仕方がないので、全ての例外を捕捉し、本来例外が捕捉されなかった場合に実行する処理を特別に実行することにした

                try
                {
                    this.ExecuteInUIThread(() =>
                    {
                        if (message == "new_account_holder")
                            NewAccountHolder(this);
                        else if (message == "new_account")
                            NewAccount(this, null, null);
                        else if (message.StartsWith("new_chat"))
                        {
                            Dictionary<string, object> obj = JSONParser.Parse(message.Substring(9)) as Dictionary<string, object>;

                            foreach (var pah in core.iAccountHolders.iPseudonymousAccountHolders)
                                if (pah.iSign == obj["pah"] as string)
                                {
                                    Ecdsa256PubKey pubKey = pah.iPubKey as Ecdsa256PubKey;
                                    Ecdsa256PrivKey privKey = pah.iPrivKey as Ecdsa256PrivKey;
                                    if (privKey == null)
                                        throw new InvalidOperationException("new_chat_pah_version");

                                    Chat chat = new Chat();
                                    chat.LoadVersion0(pah.iName, obj["message"] as string, pubKey);
                                    chat.Sign(privKey);

                                    core.iCreaNodeTest.DiffuseNewChat(chat);

                                    return;
                                }

                            throw new InvalidOperationException("new_chat_pah_not_found");
                        }
                        else if (message.StartsWith("new_transaction"))
                        {
                            NewTransactionWindow ntw = null;

                            IAccountHolder iAccountHolder = null;

                            Action _ClearAccount = () => ntw.cbAccount.Items.Clear();
                            Action _AddAccount = () =>
                            {
                                foreach (var account in iAccountHolder.iAccounts)
                                    ntw.cbAccount.Items.Add(account);
                            };

                            EventHandler<IAccount> accountAdded = (sender2, e2) => _ClearAccount.AndThen(_AddAccount).ExecuteInUIThread();

                            ntw = new NewTransactionWindow(() =>
                            {
                                if (iAccountHolder != null)
                                {
                                    iAccountHolder.iAccountAdded -= accountAdded;

                                    _ClearAccount();
                                }

                                if (ntw.rbAnonymous.IsChecked.Value)
                                    iAccountHolder = core.iAccountHolders.iAnonymousAccountHolder;
                                else
                                    iAccountHolder = ntw.cbAccountHolder.SelectedItem as IAccountHolder;

                                if (iAccountHolder != null)
                                {
                                    iAccountHolder.iAccountAdded += accountAdded;

                                    _AddAccount();
                                }
                            }, (addressString) => new Account.AccountAddress(addressString).IsValid, (obj) => (obj as IAccount).iUsableAmountWithUnconfirmed);
                            ntw.Owner = this;

                            Action _ClearAccountHolder = () => ntw.cbAccountHolder.Items.Clear();
                            Action _AddAccountHolder = () =>
                            {
                                foreach (var ah in core.iAccountHolders.iPseudonymousAccountHolders)
                                    ntw.cbAccountHolder.Items.Add(ah);
                            };

                            EventHandler balanceUpdated = (sender2, e2) => this.ExecuteInUIThread(() => ntw.UpdateBalance());

                            EventHandler<IAccountHolder> accountHolderAdded = (sender2, e2) => _ClearAccountHolder.AndThen(_AddAccountHolder).ExecuteInUIThread();

                            core.iAccountHolders.iAccountHolderAdded += accountHolderAdded;
                            core.BalanceUpdated += balanceUpdated;

                            _AddAccountHolder();

                            ntw.rbAnonymous.IsChecked = true;

                            if (ntw.ShowDialog() == true)
                                core.NewTransaction(ntw.cbAccount.SelectedItem as IAccount, new Account.AccountAddress(ntw.tbAccountToAddress.Text).Hash, new Creacoin(decimal.Parse(ntw.tbAmount.Text)), new Creacoin(decimal.Parse(ntw.tbFee.Text)));

                            core.BalanceUpdated -= balanceUpdated;
                            core.iAccountHolders.iAccountHolderAdded -= accountHolderAdded;

                            if (iAccountHolder != null)
                                iAccountHolder.iAccountAdded -= accountAdded;
                        }
                        else
                            this.RaiseError("wss_command", 5);
                    });
                }
                catch (Exception ex)
                {
                    _OnException(ex, Program.ExceptionKind.unhandled);
                }
            };

            JSON json = new JSON();

            Func<string[]> _CreateBalanceJSON = () =>
            {
                string[] usableName = json.CreateJSONPair("name", "使用可能".Multilanguage(198));
                string[] usableValue = json.CreateJSONPair("value", core.UsableBalanceWithUnconfirmed.AmountInCreacoin.Amount);
                string[] usableUnit = json.CreateJSONPair("unit", Creacoin.Name);
                string[] usable = json.CreateJSONObject(usableName, usableValue, usableUnit);

                string[] unusableName = json.CreateJSONPair("name", "使用不能".Multilanguage(199));
                string[] unusableValue = json.CreateJSONPair("value", core.UnusableBalanceWithUnconfirmed.AmountInCreacoin.Amount);
                string[] unusableUnit = json.CreateJSONPair("unit", Creacoin.Name);
                string[] unusable = json.CreateJSONObject(unusableName, unusableValue, unusableUnit);

                string[] unusableConfirmedName = json.CreateJSONPair("name", "承認済".Multilanguage(259));
                string[] unusableConfirmedValue = json.CreateJSONPair("value", core.UnusableBalance.AmountInCreacoin.Amount);
                string[] unusableConfirmedUnit = json.CreateJSONPair("unit", Creacoin.Name);
                string[] unusableConfirmed = json.CreateJSONObject(unusableConfirmedName, unusableConfirmedValue, unusableConfirmedUnit);

                string[] unusableUnconfirmedName = json.CreateJSONPair("name", "未承認".Multilanguage(260));
                string[] unusableUnconfirmedValue = json.CreateJSONPair("value", core.UnconfirmedBalance.AmountInCreacoin.Amount);
                string[] unusableUnconfirmedUnit = json.CreateJSONPair("unit", Creacoin.Name);
                string[] unusableUnconfirmed = json.CreateJSONObject(unusableUnconfirmedName, unusableUnconfirmedValue, unusableUnconfirmedUnit);

                string[] balanceName = json.CreateJSONPair("name", "残高".Multilanguage(200));
                string[] balanceValue = json.CreateJSONPair("value", core.Balance.AmountInCreacoin.Amount);
                string[] balanceUnit = json.CreateJSONPair("unit", Creacoin.Name);
                string[] balanceUsable = json.CreateJSONPair("usable", usable);
                string[] balanceUnusable = json.CreateJSONPair("unusable", unusable);
                string[] balanceUnusableConfirmed = json.CreateJSONPair("unusableConfirmed", unusableConfirmed);
                string[] balanceUnusableUnconfirmed = json.CreateJSONPair("unusableUnconfirmed", unusableUnconfirmed);
                return json.CreateJSONObject(balanceName, balanceValue, balanceUnit, balanceUsable, balanceUnusable, balanceUnusableConfirmed, balanceUnusableUnconfirmed);
            };

            Func<IAccount[], string[]> _CreateAccountsJSON = (iaccounts) =>
            {
                List<string[]> anonymousAccountsList = new List<string[]>();
                foreach (var iaccount in iaccounts)
                {
                    string[] accountName = json.CreateJSONPair("name", iaccount.iName);
                    string[] accountDescription = json.CreateJSONPair("description", iaccount.iDescription);
                    string[] accountAddress = json.CreateJSONPair("address", iaccount.iAddress);
                    anonymousAccountsList.Add(json.CreateJSONObject(accountName, accountDescription, accountAddress));
                }
                return json.CreateJSONArray(anonymousAccountsList.ToArray());
            };

            Func<string[]> _CreateAahJSON = () =>
            {
                string[] anonymousAccountHolderName = json.CreateJSONPair("name", "匿名".Multilanguage(207));
                string[] anonymousAccounts = json.CreateJSONPair("accounts", _CreateAccountsJSON(core.iAccountHolders.iAnonymousAccountHolder.iAccounts));
                return json.CreateJSONObject(anonymousAccountHolderName, anonymousAccounts);
            };

            Func<string[]> _CreatePahsJSON = () =>
            {
                List<string[]> pseudonymousAccountHoldersList = new List<string[]>();
                foreach (var pah in core.iAccountHolders.iPseudonymousAccountHolders)
                {
                    string[] pseudonymousAccountHolderName = json.CreateJSONPair("name", pah.iSign);
                    string[] pseudonymousAccounts = json.CreateJSONPair("accounts", _CreateAccountsJSON(pah.iAccounts));
                    pseudonymousAccountHoldersList.Add(json.CreateJSONObject(pseudonymousAccountHolderName, pseudonymousAccounts));
                }
                return json.CreateJSONArray(pseudonymousAccountHoldersList.ToArray());
            };

            Func<TransactionHistory, string[]> _CreateTransactionHistoryJSON = (th) =>
            {
                string[] thValidity = json.CreateJSONPair("validity", th.isValid ? "有効".Multilanguage(265) : "無効".Multilanguage(266));
                string[] thState = json.CreateJSONPair("state", th.isConfirmed ? "承認済".Multilanguage(267) : "未承認".Multilanguage(268));
                string[] thBlockIndex = json.CreateJSONPair("blockIndex", th.blockIndex);
                string[] thType = json.CreateJSONPair("type", th.type == TransactionHistoryType.mined ? "採掘".Multilanguage(269) : th.type == TransactionHistoryType.sent ? "送付".Multilanguage(270) : th.type == TransactionHistoryType.received ? "受領".Multilanguage(271) : "振替".Multilanguage(272));
                string[] thDatetime = json.CreateJSONPair("datetime", th.datetime == DateTime.MinValue ? "不明".Multilanguage(273) : th.datetime.ToString());
                string[] thId = json.CreateJSONPair("id", th.id.ToString());
                string[] thFromAddress = json.CreateJSONPair("fromAddress", json.CreateJSONArray(th.prevTxOuts.Select((elem) => new Account.AccountAddress(elem.Address).ToString()).Distinct().ToArray()));
                string[] thToAddress = json.CreateJSONPair("toAddress", json.CreateJSONArray(th.transaction.TxOutputs.Select((elem) => new Account.AccountAddress(elem.Address).ToString()).Distinct().ToArray()));
                string[] thAmount = json.CreateJSONPair("amount", th.amount.AmountInCreacoin.Amount);

                return json.CreateJSONObject(thValidity, thState, thBlockIndex, thType, thDatetime, thId, thFromAddress, thToAddress, thAmount);
            };

            Func<List<TransactionHistory>, string[]> _CreateTransactionHistoriesJSON = (ths) =>
            {
                List<string[]> transactionHistoriesList = new List<string[]>();
                foreach (var th in ths)
                    transactionHistoriesList.Add(_CreateTransactionHistoryJSON(th));
                return json.CreateJSONArray(transactionHistoriesList.ToArray());
            };

            Func<Program.LogData, string[]> _CreateLogJSON = (log) =>
            {
                string[] logType = json.CreateJSONPair("type", log.Kind.ToString());
                string[] logMessage = json.CreateJSONPair("message", log.ToString().Replace("\\", "\\\\").Replace("/", "\\/").Replace("\"", "\\\"").Replace(Environment.NewLine, "<br />").Replace("\n", "<br />").Replace("\r", "<br />"));
                return json.CreateJSONObject(logType, logMessage);
            };

            Func<Chat, string[]> _CreateChatJSON = (chat) =>
            {
                string[] chatName = json.CreateJSONPair("name", chat.NameWithTrip);
                string[] chatMessage = json.CreateJSONPair("message", chat.Message);
                return json.CreateJSONObject(chatName, chatMessage);
            };

            Action<string> _SendMessage = (message) =>
            {
                if (wss != null)
                    foreach (var wssession in wss.GetAllSessions())
                        wssession.Send(message);
            };

            Action<string[]> _SendMessages = (messages) =>
            {
                if (wss != null)
                    foreach (var wssession in wss.GetAllSessions())
                        foreach (var message in messages)
                            wssession.Send(message);
            };

            core.BalanceUpdated += (sender2, e2) => _SendMessage("balanceUpdated " + string.Join(Environment.NewLine, _CreateBalanceJSON()));
            core.blockChain.Updated += (sender2, e2) => _SendMessage("blockchainUpdated " + string.Join(Environment.NewLine, json.CreateJSONObject(json.CreateJSONPair("currentBlockIndex", core.blockChain.headBlockIndex))));
            core.transactionHistories.InvalidTransactionAdded += (sender2, e2) => _SendMessage("invalidTxAdded " + string.Join(Environment.NewLine, _CreateTransactionHistoryJSON(e2)));
            core.transactionHistories.InvalidTransactionRemoved += (sender2, e2) => _SendMessage("invalidTxRemoved " + string.Join(Environment.NewLine, json.CreateJSONObject(json.CreateJSONPair("id", e2.id.ToString()))));
            core.transactionHistories.UnconfirmedTransactionAdded += (sender2, e2) => _SendMessage("unconfirmedTxAdded " + string.Join(Environment.NewLine, _CreateTransactionHistoryJSON(e2)));
            core.transactionHistories.UnconfirmedTransactionRemoved += (sender2, e2) => _SendMessage("unconformedTxRemoved " + string.Join(Environment.NewLine, json.CreateJSONObject(json.CreateJSONPair("id", e2.id.ToString()))));
            core.transactionHistories.ConfirmedTransactionAdded += (sender2, e2) => _SendMessage("confirmedTxAdded " + string.Join(Environment.NewLine, _CreateTransactionHistoryJSON(e2)));
            core.transactionHistories.ConfirmedTransactionRemoved += (sender2, e2) => _SendMessage("confirmedTxRemoved " + string.Join(Environment.NewLine, json.CreateJSONObject(json.CreateJSONPair("id", e2.id.ToString()))));
            logger.LogAdded += (sender2, e2) => _SendMessage("logAdded " + string.Join(Environment.NewLine, _CreateLogJSON(e2)));
            core.iCreaNodeTest.ReceivedNewChat += (sender2, e2) => _SendMessage("chatAdded " + string.Join(Environment.NewLine, _CreateChatJSON(e2)));

            Action _SendAccountHolders = () => _SendMessages(new string[] { "aahUpdated " + string.Join(Environment.NewLine, _CreateAahJSON()), "pahsUpdated " + string.Join(Environment.NewLine, _CreatePahsJSON()) });

            EventHandler _AccountChanged = (sender2, e2) => _SendAccountHolders();
            EventHandler<IAccount> _AccountAdded = (sender2, e2) =>
            {
                _SendAccountHolders();

                e2.iAccountChanged += _AccountChanged;
            };
            EventHandler<IAccount> _AccountRemoved = (sender2, e2) =>
            {
                _SendAccountHolders();

                e2.iAccountChanged -= _AccountChanged;
            };

            Action<IAccountHolder> _SubscribeEvents = (accountHolder) =>
            {
                accountHolder.iAccountAdded += _AccountAdded;
                accountHolder.iAccountRemoved += _AccountRemoved;
                foreach (var account in accountHolder.iAccounts)
                    account.iAccountChanged += _AccountChanged;
            };

            _SubscribeEvents(core.iAccountHolders.iAnonymousAccountHolder);
            foreach (var pseudonymousAccountHolder in core.iAccountHolders.iPseudonymousAccountHolders)
                _SubscribeEvents(pseudonymousAccountHolder);

            core.iAccountHolders.iAccountHolderAdded += (sender2, e2) =>
            {
                _SendAccountHolders();

                _SubscribeEvents(e2);
            };
            core.iAccountHolders.iAccountHolderRemoved += (sender2, e2) =>
            {
                _SendAccountHolders();

                e2.iAccountAdded -= _AccountAdded;
                e2.iAccountRemoved -= _AccountRemoved;
                foreach (var account in e2.iAccounts)
                    account.iAccountChanged -= _AccountChanged;
            };

            WebSocketServer oldWss;
            wss = new WebSocketServer();
            wss.NewSessionConnected += (wssession) =>
            {
                if (!mws.IsWebServerAcceptExternal && !wssession.RemoteEndPoint.Address.Equals(IPAddress.Loopback) && !wssession.RemoteEndPoint.Address.Equals(IPAddress.IPv6Loopback))
                {
                    wssession.Close();

                    return;
                }

                string[] partBalanceName = json.CreateJSONPair("name", "残高".Multilanguage(201));
                string[] partBalanceDetail = json.CreateJSONPair("detail", _CreateBalanceJSON());
                string[] partBalance = json.CreateJSONObject(partBalanceName, partBalanceDetail);

                string[] accountHolderColumnName = json.CreateJSONPair("name", "口座名".Multilanguage(202));
                string[] accountHolderColumnDescription = json.CreateJSONPair("description", "説明".Multilanguage(203));
                string[] accountHolderColumnAddress = json.CreateJSONPair("address", "口座番号".Multilanguage(204));
                string[] accountHolderColumns = json.CreateJSONObject(accountHolderColumnName, accountHolderColumnDescription, accountHolderColumnAddress);

                string[] txsColumnValidty = json.CreateJSONPair("validity", "効力".Multilanguage(247));
                string[] txsColumnState = json.CreateJSONPair("state", "状態".Multilanguage(248));
                string[] txsColumnConfirmation = json.CreateJSONPair("confirmation", "確証度".Multilanguage(249));
                string[] txsColumnType = json.CreateJSONPair("type", "種類".Multilanguage(250));
                string[] txsColumnDatetime = json.CreateJSONPair("datetime", "日時".Multilanguage(251));
                string[] txsColumnId = json.CreateJSONPair("id", "取引識別子".Multilanguage(252));
                string[] txsColumnFromAddress = json.CreateJSONPair("fromAddress", "送付元口座番号".Multilanguage(253));
                string[] txsColumnToAddress = json.CreateJSONPair("toAddress", "送付先口座番号".Multilanguage(254));
                string[] txsColumnAmount = json.CreateJSONPair("amount", "金額".Multilanguage(255));
                string[] txsColumns = json.CreateJSONObject(txsColumnValidty, txsColumnState, txsColumnConfirmation, txsColumnType, txsColumnDatetime, txsColumnId, txsColumnFromAddress, txsColumnToAddress, txsColumnAmount);

                string[] invalidTxsName = json.CreateJSONPair("invalidTxsName", "無効".Multilanguage(256));
                string[] unconfirmedTxsName = json.CreateJSONPair("unconfirmedTxsName", "未承認".Multilanguage(257));
                string[] confirmedTxsName = json.CreateJSONPair("confirmedTxsName", "承認済".Multilanguage(258));

                string[] buttonNewAccountHolderName = json.CreateJSONPair("name", "新しい口座名義".Multilanguage(205));
                string[] buttonNewAccountHolderKeyName = json.CreateJSONPair("keyName", "A");
                string[] buttonNewAccountHolderKey = json.CreateJSONPair("key", ((int)Key.A).ToString());
                string[] buttonNewAccountHolder = json.CreateJSONPair("buttonNewAccountHolder", json.CreateJSONObject(buttonNewAccountHolderName, buttonNewAccountHolderKeyName, buttonNewAccountHolderKey));

                string[] buttonNewAccountName = json.CreateJSONPair("name", "新しい口座".Multilanguage(206));
                string[] buttonNewAccountKeyName = json.CreateJSONPair("keyName", "B");
                string[] buttonNewAccountKey = json.CreateJSONPair("key", ((int)Key.B).ToString());
                string[] buttonNewAccount = json.CreateJSONPair("buttonNewAccount", json.CreateJSONObject(buttonNewAccountName, buttonNewAccountKeyName, buttonNewAccountKey));

                string[] buttonNewTransactionName = json.CreateJSONPair("name", "新しい取引".Multilanguage(246));
                string[] buttonNewTransactionKeyName = json.CreateJSONPair("keyName", "T");
                string[] buttonNewTransactionKey = json.CreateJSONPair("key", ((int)Key.T).ToString());
                string[] buttonNewTransaction = json.CreateJSONPair("buttonNewTransaction", json.CreateJSONObject(buttonNewTransactionName, buttonNewTransactionKeyName, buttonNewTransactionKey));

                List<string[]> logsList = new List<string[]>();
                foreach (var log in logger.Logs.Reverse())
                    logsList.Add(_CreateLogJSON(log));

                List<string[]> chatsList = new List<string[]>();
                //foreach (var chat in core.iCreaNodeTest.re)
                //    chatsList.Add(_CreateChatJSON(chat));

                string[] partAccountName = json.CreateJSONPair("name", "受け取り口座".Multilanguage(208));
                string[] partAccountButtons = json.CreateJSONPair("accountButtons", json.CreateJSONObject(buttonNewAccountHolder, buttonNewAccount));
                string[] partAccountColumns = json.CreateJSONPair("accountHolderColumns", accountHolderColumns);
                string[] partAccountAah = json.CreateJSONPair("anonymousAccountHolder", _CreateAahJSON());
                string[] partAccountPahs = json.CreateJSONPair("pseudonymousAccountHolders", _CreatePahsJSON());
                string[] partAccount = json.CreateJSONObject(partAccountName, partAccountButtons, partAccountColumns, partAccountAah, partAccountPahs);

                string[] partLogName = json.CreateJSONPair("name", "運用記録".Multilanguage(209));
                string[] partLogItems = json.CreateJSONPair("logs", json.CreateJSONArray(logsList.ToArray()));
                string[] partLog = json.CreateJSONObject(partLogName, partLogItems);

                string[] partChatName = json.CreateJSONPair("name", "チャット".Multilanguage(211));
                string[] partChatPahSelect = json.CreateJSONPair("pahSelectDescription", "(選択してください)".Multilanguage(212));
                string[] partChatSendButton = json.CreateJSONPair("sendButtonName", "発言".Multilanguage(213));
                string[] partChatItems = json.CreateJSONPair("chats", json.CreateJSONArray(chatsList.ToArray()));
                string[] partChat = json.CreateJSONObject(partChatName, partChatPahSelect, partChatSendButton, partChatItems);

                string[] partTxName = json.CreateJSONPair("name", "取引".Multilanguage(245));
                string[] partTxButtons = json.CreateJSONPair("buttons", json.CreateJSONObject(buttonNewTransaction));
                string[] partTxTxsColumns = json.CreateJSONPair("txsColumns", txsColumns);
                string[] partTxInvalidTxs = json.CreateJSONPair("invalidTxs", _CreateTransactionHistoriesJSON(core.transactionHistories.invalidTransactionHistories));
                string[] partTxUnconfirmedTxs = json.CreateJSONPair("unconfirmedTxs", _CreateTransactionHistoriesJSON(core.transactionHistories.unconfirmedTransactionHistories));
                string[] partTxConfirmedTxs = json.CreateJSONPair("confirmedTxs", _CreateTransactionHistoriesJSON(core.transactionHistories.confirmedTransactionHistories));
                string[] partTxCurrentBlockIndex = json.CreateJSONPair("currentBlockIndex", core.blockChain.headBlockIndex);
                string[] partTx = json.CreateJSONObject(partTxName, partTxButtons, partTxTxsColumns, invalidTxsName, unconfirmedTxsName, confirmedTxsName, partTxInvalidTxs, partTxUnconfirmedTxs, partTxConfirmedTxs, partTxCurrentBlockIndex);

                string[] universeTitle = json.CreateJSONPair("title", appnameWithVersion);
                string[] universePartBalance = json.CreateJSONPair("partBalance", partBalance);
                string[] universePartAccount = json.CreateJSONPair("partAccount", partAccount);
                string[] universePartLog = json.CreateJSONPair("partLog", partLog);
                string[] universePartChat = json.CreateJSONPair("partChat", partChat);
                string[] universePartTransaction = json.CreateJSONPair("partTransaction", partTx);
                string[] universe = json.CreateJSONObject(universeTitle, universePartBalance, universePartAccount, universePartLog, universePartChat, universePartTransaction);

                string jsonString = string.Join(Environment.NewLine, universe);

                wssession.Send("initial_data " + jsonString);
            };
            wss.NewMessageReceived += newMessageReceived;
            wss.Setup(mws.PortWebSocket);
            wss.Start();

            //wb.Navigated += (sender2, e2) => ((mshtml.HTMLDocument)wb.Document).focus();
            if (isStartedWebServer)
                wb.Navigate("http://localhost:" + mws.PortWebServer.ToString() + "/");

            mws.SettingsChanged += (sender2, e2) =>
            {
                if (mws.isPortWebServerAltered)
                {
                    if (hl != null)
                    {
                        hl.Abort();
                        hl.Close();
                    }

                    isStartedWebServer = false;

                    _StartWebServer();

                    if (isStartedWebServer)
                        wb.Navigate("http://localhost:" + mws.PortWebServer.ToString() + "/");
                }
                else
                {
                    if (mws.isIsWallpaperAltered || mws.isWallpaperAltered || mws.isWallpaperOpacityAltered)
                    {
                        resources.Remove(wallpaperFileName);
                        wallpaperFileName = "/back" + DateTime.Now.Ticks.ToString() + ".png";
                        resources.Add(wallpaperFileName, new WebResourceWallpaper(mws.IsWallpaper ? mws.Wallpaper : null, mws.WallpaperOpacity));

                        foreach (var wssession in wss.GetAllSessions())
                            wssession.Send("wallpaper " + wallpaperFileName);
                    }
                    if (mws.isPortWebSocketAltered)
                    {
                        (resources["/"] as WebResourceHome).port = (ushort)mws.PortWebSocket;

                        //2014/07/02
                        //<未実装>古いイベントの登録を解除していない
                        oldWss = wss;
                        wss = new WebSocketServer();
                        wss.NewSessionConnected += (session) =>
                        {
                            if (oldWss != null)
                            {
                                oldWss.Stop();
                                oldWss = null;
                            }
                        };
                        wss.NewMessageReceived += newMessageReceived;
                        wss.Setup(mws.PortWebSocket);
                        wss.Start();

                        foreach (var wssession in oldWss.GetAllSessions())
                            wssession.Send("wss " + mws.PortWebSocket.ToString());
                    }
                    if (mws.isIsDefaultUiAltered || mws.isUiFilesDirectoryAltered)
                    {
                        resources.Remove("/");
                        resources.Add("/", new WebResourceHome(mws.IsDefaultUi, "CREA2014.WebResources.home2.htm", Path.Combine(mws.UiFilesDirectory, "home2.htm"), entryAssembly));

                        wb.Navigate("http://localhost:" + mws.PortWebServer.ToString() + "/");
                    }
                }
            };

            LoadCompleted(this, EventArgs.Empty);
        }