Crossfire Server, Trunk
SoundFiles.cpp
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 2022 the Crossfire Development Team
5  *
6  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
7  * welcome to redistribute it under certain conditions. For details, please
8  * see COPYING and LICENSE.
9  *
10  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
11  */
12 
13 #include "SoundFiles.h"
14 #include "../CRESettings.h"
15 #include "SoundFile.h"
16 #include <QDir>
17 #include <QFile>
18 #include <QTextStream>
19 #include <QDebug>
20 #include "global.h"
21 
22 SoundFiles::SoundFiles(AssetWrapper *parent) : AssetWrapper(parent, "SoundFiles") {
23  setProperty(tipProperty, tr("Display all sound files."));
24  refreshSounds();
25 }
26 
29  QString path(settings.soundsDirectory());
30  if (path.isEmpty()) {
31  return;
32  }
33  QDir dir(path);
34  if (!dir.exists()) {
35  return;
36  }
37 
39 
40  for (auto sound : mySounds) {
41  delete sound;
42  }
43  mySounds.clear();
44 
45  std::map<std::string, std::string> soundConf;
46  QFile file(dir.filePath("sounds.conf"));
47  if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
48  QTextStream in(&file);
49  while (!in.atEnd()) {
50  QString line = in.readLine();
51  if (line.isEmpty() || line.startsWith('#')) {
52  continue;
53  }
54  auto split = line.split(':');
55  if (split.length() != 3) {
56  continue;
57  }
58  soundConf[split[0].toStdString()] = split[2].toStdString();
59  }
60  } else {
61  qDebug() << tr("Unable to open sound configuration file %1/sounds.conf").arg(path);
62  }
63 
64  auto files = dir.entryList(QDir::Files, QDir::SortFlag::IgnoreCase | QDir::Name);
65  for (auto file : files) {
66  if (file.endsWith(".ogg") || file.endsWith(".wav")) {
67  std::vector<std::string> events;
68  for (const auto &sc : soundConf) {
69  if (sc.second == file.toStdString()) {
70  events.push_back(sc.first);
71  }
72  }
73  mySounds.push_back(new SoundFile(events, this, file));
74  continue;
75  }
76  if (file.endsWith(".LICENSE")) {
77  auto name = file.left(file.length() - 8);
78  auto it = std::find_if(mySounds.cbegin(), mySounds.cend(), [&name] (const auto &sound) { return sound->displayName() == name; });
79  if (it != mySounds.cend()) {
80  auto br = bufferreader_init_from_file(nullptr, dir.filePath(file).toStdString().data(), "Failed to open LICENSE file %s: %s", llevError);
81  if (br) {
82  LicenseManager::parseLicenseFile(br, "", (*it)->license());
84  }
85  }
86  continue;
87  }
88  }
89 
91 }
92 
94  return mySounds[index];
95 }
96 
98  for (size_t i = 0; i < mySounds.size(); ++i) {
99  if (mySounds[i] == child) {
100  return static_cast<int>(i);
101  }
102  }
103  return -1;
104 }
105 
106 QString SoundFiles::licenseInformation() const {
107  if (mySounds.empty()) {
108  return tr("No sound file found");
109  }
110  size_t with = 0;
111  for (const auto &sound : mySounds) {
112  if (!sound->license().empty()) {
113  ++with;
114  }
115  }
116  size_t percent = 100 * with / mySounds.size();
117  if (percent == 100 && with < mySounds.size()) {
118  percent = 99;
119  }
120  return tr("%1 sound files with license information on %2 (%3%)").arg(with).arg(mySounds.size()).arg(percent);
121 }
AssetWrapper::AfterLayoutChange
@ AfterLayoutChange
Definition: AssetWrapper.h:33
global.h
settings
struct Settings settings
Definition: init.cpp:139
llevError
@ llevError
Definition: logger.h:11
SoundFiles::SoundFiles
SoundFiles(AssetWrapper *parent)
Definition: SoundFiles.cpp:22
mad_mage_user.file
file
Definition: mad_mage_user.py:15
bufferreader_destroy
void bufferreader_destroy(BufferReader *br)
Definition: bufferreader.cpp:40
AssetWrapper::tipProperty
static const char * tipProperty
Definition: AssetWrapper.h:34
bufferreader_init_from_file
BufferReader * bufferreader_init_from_file(BufferReader *br, const char *filepath, const char *failureMessage, LogLevel failureLevel)
Definition: bufferreader.cpp:65
is_valid_types_gen.line
line
Definition: is_valid_types_gen.py:34
AssetWrapper
Definition: AssetWrapper.h:25
python_init.path
path
Definition: python_init.py:8
events
static QHash< QString, archetype * > events
Definition: CREMapPanel.cpp:24
SoundFiles.h
SoundFiles::mySounds
std::vector< SoundFile * > mySounds
Definition: SoundFiles.h:38
SoundFiles::refreshSounds
void refreshSounds()
Definition: SoundFiles.cpp:27
CRESettings
Definition: CRESettings.h:21
AssetWrapper::BeforeLayoutChange
@ BeforeLayoutChange
Definition: AssetWrapper.h:33
npc_dialog.index
int index
Definition: npc_dialog.py:102
SoundFiles::childIndex
virtual int childIndex(AssetWrapper *child) override
Definition: SoundFiles.cpp:97
SoundFile.h
LicenseManager::parseLicenseFile
static void parseLicenseFile(BufferReader *reader, const char *filename, std::vector< LicenseItem > &items)
Definition: LicenseManager.cpp:57
bigchest.Name
Name
Definition: bigchest.py:18
AssetWrapper::markModified
void markModified(ChangeType change, int extra=0)
Definition: AssetWrapper.h:55
SoundFiles::child
virtual AssetWrapper * child(int index) override
Definition: SoundFiles.cpp:93
split
static std::vector< std::string > split(const std::string &field, const std::string &by)
Definition: mapper.cpp:2606
SoundFile
Definition: SoundFile.h:19
give.name
name
Definition: give.py:27
SoundFiles::licenseInformation
QString licenseInformation
Definition: SoundFiles.h:23