1 #include "network_cmd_scenario.h"
2 
3 #include "network_packet.h"
4 #include "network_socket_list.h"
5 #include "../simworld.h"
6 #include "../dataobj/scenario.h"
7 #include "../dataobj/environment.h"
8 #include "../script/script.h"
9 
10 
init(script_vm_t * script)11 void nwc_scenario_t::init(script_vm_t *script)
12 {
13 	script->register_callback(&nwc_scenario_t::record_result, "nwc_scenario_t_record_result");
14 }
15 
16 
record_result(const char * function,plainstring result,uint32 client_id)17 bool nwc_scenario_t::record_result(const char* function, plainstring result, uint32 client_id)
18 {
19 	SOCKET sock = socket_list_t::get_socket(client_id);
20 	if (sock == INVALID_SOCKET) {
21 		return false;
22 	}
23 	nwc_scenario_t nwc;
24 	nwc.what = CALL_SCRIPT_ANSWER;
25 	nwc.function = function;
26 	nwc.result = result;
27 	nwc.send( sock );
28 	return true;
29 }
30 
rdwr()31 void nwc_scenario_t::rdwr()
32 {
33 	network_command_t::rdwr();
34 	packet->rdwr_short(what);
35 	packet->rdwr_short(won);
36 	packet->rdwr_short(lost);
37 	packet->rdwr_str(function);
38 	packet->rdwr_str(result);
39 }
40 
41 
execute(karte_t * welt)42 bool nwc_scenario_t::execute(karte_t *welt)
43 {
44 	scenario_t *scen = welt->get_scenario();
45 	if (scen == NULL  ||  !scen->is_scripted()) {
46 		return true;
47 	}
48 	script_vm_t *script = scen->script;
49 
50 	if (what == OPEN_SCEN_WIN) {
51 		// open window on server and clients
52 		scen->open_info_win(function);
53 		return true;
54 	}
55 
56 	if (env_t::server) {
57 		switch (what) {
58 			case CALL_SCRIPT:
59 			case CALL_SCRIPT_ANSWER: {
60 				// register callback to send result back to client if script is delayed.
61 				script->prepare_callback("nwc_scenario_t_record_result", 2, function, "", socket_list_t::get_client_id( packet->get_sender() ) );
62 				plainstring res = dynamic_string::fetch_result(function, script, NULL, what==CALL_SCRIPT_ANSWER);
63 				// clear callback, in case function call was successfull
64 				script->clear_pending_callback();
65 
66 				nwc_scenario_t nwc;
67 				nwc.what = CALL_SCRIPT_ANSWER;
68 				nwc.function = function;
69 				nwc.result = res;
70 				nwc.send( packet->get_sender() );
71 				break;
72 			}
73 			case UPDATE_WON_LOST:
74 			default: ;
75 		}
76 	}
77 	else {
78 		switch (what) {
79 			case CALL_SCRIPT_ANSWER:
80 				// store result, call listening string
81 				dynamic_string::record_result(function, result);
82 				break;
83 
84 			case UPDATE_WON_LOST:
85 				scen->update_won_lost(won, lost);
86 				break;
87 
88 			default: ;
89 		}
90 	}
91 	return true;
92 }
93 
94 
do_command(karte_t * welt)95 void nwc_scenario_rules_t::do_command(karte_t *welt)
96 {
97 	scenario_t *scen = welt->get_scenario();
98 
99 	scen->intern_forbid(rule, forbid);
100 	rule = NULL; // pointer is now invalid
101 }
102 
103 
rdwr()104 void nwc_scenario_rules_t::rdwr()
105 {
106 	network_broadcast_world_command_t::rdwr();
107 	rule->rdwr(packet);
108 	packet->rdwr_bool(forbid);
109 }
110 
111 
nwc_scenario_rules_t(const nwc_scenario_rules_t & nwr)112 nwc_scenario_rules_t::nwc_scenario_rules_t(const nwc_scenario_rules_t& nwr)
113 : network_broadcast_world_command_t(NWC_SCENARIO_RULES, nwr.get_sync_step(), nwr.get_map_counter())
114 {
115 	forbid = nwr.forbid;
116 	rule = new scenario_t::forbidden_t(*nwr.rule);
117 }
118 
119 
clone(karte_t *)120 network_broadcast_world_command_t* nwc_scenario_rules_t::clone(karte_t *)
121 {
122 	// scenario scripts only run on server
123 	if (socket_list_t::get_client_id(packet->get_sender()) != 0) {
124 		// not sent by server
125 		return NULL;
126 	}
127 	return new nwc_scenario_rules_t(*this);
128 }
129