2 This program is free software; you can redistribute it and/or modify
3 it under the terms of the GNU General Public License as published by
4 the Free Software Foundation; either version 2 of the License, or
5 (at your option) any later version.
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
12 You should have received a copy of the GNU General Public License along
13 with this program; if not, write to the Free Software Foundation, Inc.,
14 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "AgentInjector.h"
21 #include "c1cobfile.h"
24 #include <boost/filesystem/path.hpp>
25 #include <boost/filesystem/convenience.hpp>
27 #include <QMessageBox>
30 namespace fs
= boost::filesystem
;
32 AgentInjector::AgentInjector(QWidget
*parent
) : QDialog(parent
) {
35 connect(ui
.injectButton
, SIGNAL(clicked()), this, SLOT(onInject()));
36 connect(ui
.removeButton
, SIGNAL(clicked()), this, SLOT(onRemove()));
37 connect(ui
.agentList
, SIGNAL(currentItemChanged(QListWidgetItem
*, QListWidgetItem
*)), this, SLOT(onSelect(QListWidgetItem
*, QListWidgetItem
*)));
38 connect(ui
.agentList
, SIGNAL(currentItemChanged(QListWidgetItem
*, QListWidgetItem
*)), ui
.imagePreview
, SLOT(onSelect(QListWidgetItem
*, QListWidgetItem
*)));
40 setAttribute(Qt::WA_QuitOnClose
, false);
47 AgentInjector::~AgentInjector() {
51 void AgentInjector::onSelect(QListWidgetItem
*current
, QListWidgetItem
*prev
) {
54 ui
.injectButton
->setEnabled(true);
56 if (engine
.version
== 2) {
57 cobAgentBlock
*b
= (cobAgentBlock
*)current
->data(Qt::UserRole
).value
<void *>();
59 ui
.Description
->setText(b
->description
.c_str());
60 ui
.removeButton
->setEnabled(b
->removescript
.size() != 0);
62 ui
.removeButton
->setEnabled(false); // TODO: support remover files!
63 ui
.Description
->setText("");
67 void AgentInjector::resetAgents() {
68 ui
.agentList
->clear();
69 ui
.injectButton
->setEnabled(false);
70 ui
.removeButton
->setEnabled(false);
72 for (std::vector
<class cobFile
*>::iterator i
= cobfiles
.begin(); i
!= cobfiles
.end(); i
++) {
77 void AgentInjector::readAgents() {
80 for (unsigned int i
= 0; i
< world
.data_directories
.size(); i
++) {
81 fs::path p
= world
.data_directories
[i
];
82 if (engine
.version
== 2) p
= p
/ "/Objects/";
83 if (!fs::exists(p
) || !fs::is_directory(p
)) {
87 fs::directory_iterator end_itr
; // default constructor is the end
88 for (fs::directory_iterator
itr(p
); itr
!= end_itr
; itr
++) {
89 std::string cobext
= fs::extension(itr
->path());
90 std::transform(cobext
.begin(), cobext
.end(), cobext
.begin(), (int(*)(int))tolower
); // downcase
91 if (cobext
!= ".cob") continue;
93 std::string cob
= itr
->path().native_file_string();
95 if (engine
.version
== 1) {
96 std::ifstream
cobstream(cob
.c_str(), std::ios::binary
);
97 if (!cobstream
.fail()) {
98 c1cobfile
cobfile(cobstream
);
99 QListWidgetItem
*newItem
= new QListWidgetItem(cobfile
.name
.c_str(), ui
.agentList
);
100 newItem
->setToolTip(cob
.c_str());
102 } else if (engine
.version
== 2) {
103 cobFile
*cobfile
= new cobFile(itr
->path());
104 cobfiles
.push_back(cobfile
);
106 for (std::vector
<cobBlock
*>::iterator i
= cobfile
->blocks
.begin(); i
!= cobfile
->blocks
.end(); i
++) {
107 if ((*i
)->type
!= "agnt") continue;
108 cobAgentBlock
*a
= new cobAgentBlock(*i
);
109 QListWidgetItem
*newItem
= new QListWidgetItem(a
->name
.c_str(), ui
.agentList
);
110 newItem
->setToolTip(cob
.c_str());
111 newItem
->setData(Qt::UserRole
, QVariant::fromValue((void *)a
));
118 void AgentInjector::onInject() {
121 if (!ui
.agentList
->currentItem()) return;
123 if (engine
.version
== 1) {
124 QString filename
= ui
.agentList
->currentItem()->toolTip();
125 std::ifstream
cobstream(filename
.toAscii(), std::ios::binary
);
126 if (cobstream
.fail()) {
127 return; // TODO: throw some kind of warning or something
130 c1cobfile
cobfile(cobstream
);
131 for (unsigned int i
= 0; i
< cobfile
.scripts
.size(); i
++) {
132 idata
+= cobfile
.scripts
[i
] + "\n";
134 for (unsigned int i
= 0; i
< cobfile
.imports
.size(); i
++) {
135 idata
+= "iscr," + cobfile
.imports
[i
] + "\n";
137 } else if (engine
.version
== 2) {
138 cobAgentBlock
*b
= (cobAgentBlock
*)ui
.agentList
->currentItem()->data(Qt::UserRole
).value
<void *>();
141 cobFile
*cobfile
= b
->getParent()->getParent();
145 assert(b
->deptypes
.size() == b
->depnames
.size());
146 for (unsigned int i
= 0; i
< b
->deptypes
.size(); i
++) {
147 unsigned short type
= b
->deptypes
[i
];
148 std::string name
= b
->depnames
[i
];
150 unsigned int praytype
;
152 case 0: praytype
= 2; break;
153 case 1: praytype
= 1; break;
154 default: QMessageBox::warning(this, tr("Couldn't inject:"), tr("Unknown dependency type")); return;
157 std::string directory
= world
.praymanager
.getResourceDir(praytype
);
158 caos_assert(!directory
.empty());
160 fs::path possiblefile
= fs::path(directory
, fs::native
) / fs::path(name
, fs::native
);
161 if (!world
.findFile(possiblefile
.native_directory_string()).empty()) continue; // TODO: update file if necessary?
163 std::vector
<cobBlock
*>::iterator j
;
165 std::string encounteredfilenames
;
167 // check all of the available file blocks in this COB
168 for (j
= cobfile
->blocks
.begin(); j
!= cobfile
->blocks
.end(); j
++) {
169 if ((*j
)->type
!= "file") continue;
170 cobFileBlock
*a
= new cobFileBlock(*j
);
171 if (a
->filetype
== type
&& a
->filename
== name
) {
173 fs::path dir
= fs::path(world
.getUserDataDir(), fs::native
) / fs::path(directory
, fs::native
);
174 if (!fs::exists(dir
))
175 fs::create_directory(dir
);
176 assert(fs::exists(dir
) && fs::is_directory(dir
)); // TODO: error handling
178 fs::path outputfile
= dir
/ fs::path(name
, fs::native
);
179 assert(!fs::exists(outputfile
));
181 std::ofstream
output(outputfile
.native_directory_string().c_str(), std::ios::binary
);
182 output
.write((char *)a
->getFileContents(), a
->filesize
);
184 a
->getParent()->free();
188 encounteredfilenames
+= " '" + a
->filename
+ "'";
191 if (j
== cobfile
->blocks
.end()) {
192 // Couldn't find dependency!
193 std::string error
= "Failed to find required dependency '" + name
+ "', possible choices were:" + encounteredfilenames
;
194 QMessageBox::warning(this, tr("Couldn't inject:"), error
.c_str());
200 for (unsigned int i
= 0; i
< b
->scripts
.size(); i
++) {
201 idata
+= b
->scripts
[i
] + "\n";
203 idata
+= "iscr," + b
->installscript
+ "\n";
208 std::string result
= engine
.executeNetwork(idata
);
210 QMessageBox::warning(this, tr("Injection returned data (error?):"), result
.c_str());
213 void AgentInjector::onRemove() {
216 if (!ui
.agentList
->currentItem()) return;
218 if (engine
.version
== 2) {
219 cobAgentBlock
*b
= (cobAgentBlock
*)ui
.agentList
->currentItem()->data(Qt::UserRole
).value
<void *>();
222 idata
+= b
->removescript
+= "\n";
227 std::string result
= engine
.executeNetwork(idata
);
229 QMessageBox::warning(this, tr("Removal returned data (error?):"), result
.c_str());