EvEmu  0.8.4
11 September 2021
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
ImageServer.cpp
Go to the documentation of this file.
1 /*
2  ------------------------------------------------------------------------------------
3  LICENSE:
4  ------------------------------------------------------------------------------------
5  This file is part of EVEmu: EVE Online Server Emulator
6  Copyright 2006 - 2021 The EVEmu Team
7  For the latest information visit https://evemu.dev
8  ------------------------------------------------------------------------------------
9  This program is free software; you can redistribute it and/or modify it under
10  the terms of the GNU Lesser General Public License as published by the Free Software
11  Foundation; either version 2 of the License, or (at your option) any later
12  version.
13 
14  This program is distributed in the hope that it will be useful, but WITHOUT
15  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
17 
18  You should have received a copy of the GNU Lesser General Public License along with
19  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
20  Place - Suite 330, Boston, MA 02111-1307, USA, or go to
21  http://www.gnu.org/copyleft/lesser.txt.
22  ------------------------------------------------------------------------------------
23  Author: caytchen
24 */
25 
30 
31 const char *const ImageServer::FallbackURL = "http://image.eveonline.com/";
32 
33 const char *const ImageServer::Categories[] = {
34  "Alliance",
35  "Corporation",
36  "Character",
37  "InventoryType",
38  "Render" };
39 
41 
43 {
44  std::stringstream urlBuilder;
45  urlBuilder << "http://" << sConfig.net.imageServer << ":" << sConfig.net.imageServerPort << "/";
46  _url = urlBuilder.str();
47 
48  _basePath = sConfig.files.imageDir;
49  if (_basePath[_basePath.size() - 1] != '/')
50  _basePath += "/";
51 
52  sLog.Cyan(" ImageServer", "Image Server URL: %s", _url.c_str());
53  sLog.Cyan(" ImageServer", "Image Server path: %s", _basePath.c_str());
54 
55  if (CreateDirectory( _basePath.c_str(), NULL ) == 0) {
56  for (int i = 0; i < CategoryCount; i++) {
57  std::string subdir = _basePath;
58  subdir.append(Categories[i]);
59  CreateDirectory( subdir.c_str(), NULL );
60  }
61  } /* else directory probably exists */
62  sLog.Blue(" ImageServer", "Image Server Initalized.");
63 }
64 
65 void ImageServer::ReportNewImage(uint32 accountID, std::shared_ptr<std::vector<char> > imageData)
66 {
67  sLog.Warning(" ImageServer"," ReportNewImage() called.");
68  Lock lock(_limboLock);
69 
70  if (_limboImages.find(accountID) != _limboImages.end()) {
71  _limboImages.insert(std::pair<uint32,std::shared_ptr<std::vector<char> > >(accountID, imageData));
72  } else {
73  _limboImages[accountID] = imageData;
74  }
75 }
76 
77 void ImageServer::ReportNewCharacter(uint32 creatorAccountID, uint32 characterID)
78 {
79  sLog.Warning(" ImageServer"," ReportNewCharacter() called.");
80  Lock lock(_limboLock);
81 
82  // check if we received an image from this account previously
83  if (_limboImages.find(creatorAccountID) == _limboImages.end()) {
84  sLog.Error(" ImageServer"," Image not received for characterID %u.", characterID);
86  return;
87  }
88 
89  // we have, so save it
90  //std::ofstream stream;
91  std::string dirName = "Character";
92  std::string path(GetFilePath(dirName, characterID, 512));
93  FILE * fp = fopen(path.c_str(), "wb");
94 
95  //stream.open(path, std::ios::binary | std::ios::trunc | std::ios::out);
96  std::shared_ptr<std::vector<char> > data = _limboImages[creatorAccountID];
97 
98  fwrite(&((*data)[0]), 1, data->size(), fp);
99  fclose(fp);
100 
101  //std::copy(data->begin(), data->end(), std::ostream_iterator<char>(stream));
102  //stream.flush();
103  //stream.close();
104 
106  // github.com/nothings/stb/blob/master/stb_image_resize.h
107  // github.com/nothings/stb/blob/master/stb_image.h
108 
109  // and delete it from our limbo map
110  _limboImages.erase(creatorAccountID);
111 
112  sLog.Green(" ImageServer", "Received image from %u and saved as %s", creatorAccountID, path.c_str());
113 }
114 
115 std::shared_ptr<std::vector<char> > ImageServer::GetImage(std::string& category, uint32 id, uint32 size)
116 {
117  sLog.Cyan(" ImageServer"," GetImage() called. Cat: %s, id: %u, size:%u", category.c_str(), id, size);
118 
119  if (!ValidateCategory(category) || !ValidateSize(category, size))
120  return std::shared_ptr<std::vector<char> >();
121 
122  //std::ifstream stream;
123  std::string path(GetFilePath(category, id, size));
124  FILE * fp = fopen(path.c_str(), "rb");
125  if (fp == NULL)
126  return std::shared_ptr<std::vector<char> >();
127  fseek(fp, 0, SEEK_END);
128  size_t length = ftell(fp);
129  fseek(fp, 0, SEEK_SET);
130 
131  //stream.open(path, std::ios::binary | std::ios::in);
132  // not found or other error
133  //if (stream.fail())
134  // return std::shared_ptr<std::vector<char> >();
135 
136  // get length
137  //stream.seekg(0, std::ios::end);
138  //int length = stream.tellg();
139  //stream.seekg(0, std::ios::beg);
140 
141  std::shared_ptr<std::vector<char> > ret = std::shared_ptr<std::vector<char> >(new std::vector<char>());
142  ret->resize(length);
143 
144  // HACK
145  //stream.read(&((*ret)[0]), length);
146  fread(&((*ret)[0]), 1, length, fp);
147 
148  return ret;
149 }
150 
151 std::string ImageServer::GetFilePath(std::string& category, uint32 id, uint32 size)
152 {
153  std::string extension = category == "Character" ? "jpg" : "png";
154 
155  // HACK: We don't have any other
156  size = 512;
157 
158  std::stringstream builder;
159  builder << _basePath << category << "/" << id << "_" << size << "." << extension;
160  return builder.str();
161 }
162 
163 bool ImageServer::ValidateSize(std::string& category, uint32 size)
164 {
165  if (category == "InventoryType")
166  return size == 64 || size == 32;
167 
168  if (category == "Alliance")
169  return size == 256 || size == 128 || size == 64 || size == 32;
170 
171  if (category == "Corporation")
172  return size == 256 || size == 128 || size == 64 || size == 32;
173 
174  // Render and Character
175  return size == 1024 || size == 512 || size == 256 || size == 128 || size == 64 || size == 40 || size == 32;
176 }
177 
178 bool ImageServer::ValidateCategory(std::string& category)
179 {
180  for (int i = 0; i < 5; i++)
181  if (category == Categories[i])
182  return true;
183  return false;
184 }
185 
186 std::string& ImageServer::url()
187 {
188  return _url;
189 }
190 
192 {
193  _ioThread = std::shared_ptr<boost::asio::detail::thread>(new boost::asio::detail::thread(std::bind(&ImageServer::RunInternal, this)));
194 }
195 
197 {
198  _io->stop();
199  _ioThread->join();
200 }
201 
203 {
204  _io = std::shared_ptr<boost::asio::io_context>(new boost::asio::io_context());
205  _listener = std::shared_ptr<ImageServerListener>(new ImageServerListener(*_io));
206  _io->run();
207 }
208 
209 ImageServer::Lock::Lock(boost::asio::detail::mutex& mutex)
210  : _mutex(mutex)
211 {
212  _mutex.lock();
213 }
214 
216 {
217  _mutex.unlock();
218 }
#define sConfig
A macro for easier access to the singleton.
static const char *const Categories[]
Definition: ImageServer.h:63
static const char *const FallbackURL
Definition: ImageServer.h:68
boost::asio::detail::mutex & _mutex
Definition: ImageServer.h:89
void ReportNewCharacter(uint32 creatorAccountID, uint32 characterID)
Definition: ImageServer.cpp:77
void ReportNewImage(uint32 accountID, std::shared_ptr< std::vector< char > > imageData)
Definition: ImageServer.cpp:65
std::shared_ptr< std::vector< char > > GetImage(std::string &category, uint32 id, uint32 size)
std::string & url()
boost::asio::detail::mutex _limboLock
Definition: ImageServer.h:81
void RunInternal()
#define sLog
Evaluates to a NewLog instance.
Definition: LogNew.h:250
bool ValidateSize(std::string &category, uint32 size)
int CreateDirectory(const char *name, void *)
Definition: eve-compat.cpp:46
std::shared_ptr< ImageServerListener > _listener
Definition: ImageServer.h:78
Handles listening for new clients.
std::string _url
Definition: ImageServer.h:79
static const uint32 CategoryCount
Definition: ImageServer.h:64
Lock(boost::asio::detail::mutex &mutex)
unsigned __int32 uint32
Definition: eve-compat.h:50
std::shared_ptr< boost::asio::detail::thread > _ioThread
Definition: ImageServer.h:76
std::shared_ptr< boost::asio::io_context > _io
Definition: ImageServer.h:77
std::string _basePath
Definition: ImageServer.h:80
std::string GetFilePath(std::string &category, uint32 id, uint32 size)
bool ValidateCategory(std::string &category)
std::unordered_map< uint32, std::shared_ptr< std::vector< char > > > _limboImages
Definition: ImageServer.h:75