aboutsummaryrefslogtreecommitdiff
path: root/diplomacy/web/src/gui/utils/load_game_from_disk.js
blob: a65e1dfac1e3da7f68ea8717c06853ac23b1caf1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
// ==============================================================================
// Copyright (C) 2019 - Philip Paquette, Steven Bocco
//
//  This program is free software: you can redistribute it and/or modify it under
//  the terms of the GNU Affero General Public License as published by the Free
//  Software Foundation, either version 3 of the License, or (at your option) any
//  later version.
//
//  This program is distributed in the hope that it will be useful, but WITHOUT
//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
//  FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
//  details.
//
//  You should have received a copy of the GNU Affero General Public License along
//  with this program.  If not, see <https://www.gnu.org/licenses/>.
// ==============================================================================
import $ from "jquery";
import {STRINGS} from "../../diplomacy/utils/strings";
import {Game} from "../../diplomacy/engine/game";

export function loadGameFromDisk() {
    return new Promise((onLoad, onError) => {
        const input = $(document.createElement('input'));
        input.attr("type", "file");
        input.trigger('click');
        input.change(event => {
            const file = event.target.files[0];
            if (!file.name.match(/\.json$/i)) {
                onError(`Invalid JSON filename ${file.name}`);
                return;
            }
            const reader = new FileReader();
            reader.onload = () => {
                const savedData = JSON.parse(reader.result);
                const gameObject = {};
                gameObject.game_id = `(local) ${savedData.id}`;
                gameObject.map_name = savedData.map;
                gameObject.rules = savedData.rules;
                gameObject.state_history = {};
                gameObject.message_history = {};
                gameObject.order_history = {};
                gameObject.result_history = {};

                // Load all saved phases (expect the latest one) to history fields.
                for (let i = 0; i < savedData.phases.length - 1; ++i) {
                    const savedPhase = savedData.phases[i];
                    const gameState = savedPhase.state;
                    const phaseOrders = savedPhase.orders || {};
                    const phaseResults = savedPhase.results || {};
                    const phaseMessages = {};
                    if (savedPhase.messages) {
                        for (let message of savedPhase.messages) {
                            phaseMessages[message.time_sent] = message;
                        }
                    }
                    if (!gameState.name)
                        gameState.name = savedPhase.name;
                    gameObject.state_history[gameState.name] = gameState;
                    gameObject.message_history[gameState.name] = phaseMessages;
                    gameObject.order_history[gameState.name] = phaseOrders;
                    gameObject.result_history[gameState.name] = phaseResults;
                }

                // Load latest phase separately and use it later to define the current game phase.
                const latestPhase = savedData.phases[savedData.phases.length - 1];
                const latestGameState = latestPhase.state;
                const latestPhaseOrders = latestPhase.orders || {};
                const latestPhaseResults = latestPhase.results || {};
                const latestPhaseMessages = {};
                if (latestPhase.messages) {
                    for (let message of latestPhase.messages) {
                        latestPhaseMessages[message.time_sent] = message;
                    }
                }
                if (!latestGameState.name)
                    latestGameState.name = latestPhase.name;
                // TODO: NB: What if latest phase in loaded JSON contains order results? Not sure if it is well handled.
                gameObject.result_history[latestGameState.name] = latestPhaseResults;

                gameObject.messages = [];
                gameObject.role = STRINGS.OBSERVER_TYPE;
                gameObject.status = STRINGS.COMPLETED;
                gameObject.timestamp_created = 0;
                gameObject.deadline = 0;
                gameObject.n_controls = 0;
                gameObject.registration_password = '';
                const game = new Game(gameObject);

                // Set game current phase and state using latest phase found in JSON file.
                game.setPhaseData({
                    name: latestGameState.name,
                    state: latestGameState,
                    orders: latestPhaseOrders,
                    messages: latestPhaseMessages
                });
                onLoad(game);
            };
            reader.readAsText(file);
        });
    });
}