From dbde78a7d62a50d6bd4452fa6f7e2d477516095d Mon Sep 17 00:00:00 2001 From: vedantlohare Date: Fri, 18 Apr 2025 22:16:57 +0530 Subject: [PATCH 1/2] Add files via upload --- otw (1).md | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 otw (1).md diff --git a/otw (1).md b/otw (1).md new file mode 100644 index 0000000..48d8836 --- /dev/null +++ b/otw (1).md @@ -0,0 +1,99 @@ +#LEVEL 0 +What the level asked for: Logging in to the game via SSH +Logic used: *Used # ssh bandit0@bandit.labs.overthewire.org -p 2220 # with password "bandit0". + *read the "readme" file using command ## cat readme ##. + +#LEVEL 1 +What the level asked for: *Read a file named "-" which is also used in commands so can't be used directly as file name. +Logic used: *Used ## ssh bandit1@bandit.labs.overthewire.org -p 2220 ## with password "ZjLjTmM6FvvyRnrb2rfNWOZOTa6ip5If". + *Use # cat ./- # to bypass filename error. + ./ specifies the current directory and prevents - from being interpreted as a command. + +#LEVEL 2 +What the level asked for: Reading a file with spaces in its name. +Logic used: *Used # ssh bandit2@bandit.labs.overthewire.org -p 2220 # with password "263JGJPfgU6LtdEvgfWU1XP5yac29mFx". + *Included spaces in file name itself by using double quotes and making it as a string. # cat "spaces in this filename" #. + +#LEVEL 3 +What the level asked for: Finding a hidden file. +Logic used: *Used # ssh bandit3@bandit.labs.overthewire.org -p 2220 # with password "MNk8KNH3Usiio41PRUEoDFPqfxLPlSmx". + *Used # ls -a # which lists hidden files (starting with .), and # cat # reads the hidden file. + +#LEVEL 4 +What the level asked for: Identifying the only human-readable file. +Logic used: *Used # ssh bandit4@bandit.labs.overthewire.org -p 2220 # with password "2WmrDFRmJIq3IPxneAaMGhap0pFhF3NJ". + *Used the # file # command to check the file type for each file listed using # ls #. + *# file file_name # the showing ASCII TXT is the required file. +#LEVEL 5 +What the level asked for: Find a file with specific properties (1033 bytes, non-executable and human-readable). +Logic used: *Used # ssh bandit5@bandit.labs.overthewire.org -p 2220 # with password "4oQYVPkxZOOEOO5pTW81FB8j8lxXGUQw". + *# find . -size 1033c -type f ! -executable -readable # + * find command used to locate a file file in current directory of size 1033bytes(using -size 1033cc command), type of file (-type f command),non-executable(using ! -executable command) and + readable(using -readable command). + +#LEVEL 6 +What the level asked for: Locate a file owned by user bandit7 and group bandit6. +Logic used: *Used # ssh bandit6@bandit.labs.overthewire.org -p 2220 # with password "HWasnPhtq9AVKe0dmk45nxy20cvUa6EG". + *# find / -user bandit7 -group bandit6 2>/dev/null # + *Search the entire system (/) for files owned by bandit7 and group bandit6. 2>/dev/null hides errors. + +#LEVEL 7 +What the level asked for: Extract a password next to the word "millionth" stored in the file data.txt +Logic used: *Used # ssh bandit7@bandit.labs.overthewire.org -p 2220 # with password "morbNTDkSW6jIlUc0ymOdMaLnOlFVAaj". + *# grep 'millionth' data.txt # + *(grep) searches for the line containing the keyword "millionth" in file data.txt + +#LEVEL 8 +What the level asked for: Find the only unique line in a file of duplicates. +Logic used: *Used # ssh bandit8@bandit.labs.overthewire.org -p 2220 # with password "dfwvzFQi4mU0wfNbFOe9RoWskMLg7eEc". + *# sort data.txt | uniq -u # + *(sort) puts the lines in the file in order; (uniq -u) filters out duplicates, leaving only the unique line. + +#LEVEL 9 +What the level asked for: Extract a human-readable string from binary data which has multiple "=" preceeding it. +Logic used: *Used # ssh bandit9@bandit.labs.overthewire.org -p 2220 # with password "4CKMh1JI91bUIZZPXDqGanal4xvAg0JM". + *# strings data.txt | grep '==' # + *(strings) extracts human-readable text from binaries; (grep) finds lines with == in a file named data.txt + +#LEVEL 10 +What the level asked for: Decode base64 data. +Logic used: *Used # ssh bandit10@bandit.labs.overthewire.org -p 2220 # with password "FGUW5ilLVJrxX9kMYMmlN4MgbpfMiqey". + *# base64 -d data.txt # + *(base64 -d) decodes the Base64-encoded password which can then be printed by using (cat). + +#LEVEL 11 +What the level asked for: Recover the password stored in the file data.txt, where all lowercase (a-z) and uppercase (A-Z) letters have been rotated by 13 positions +Logic used: *Used # ssh bandit11@bandit.labs.overthewire.org -p 2220 # with password "dtR173fZKb0RRsDFSGsg2RWnpNVj3qRr". + *# tr 'A-Za-z' 'N-ZA-Mn-za-m' < data.txt # + *(tr) performs ROT13 substitution (shifts letters by 13 positions). + +#LEVEL 12 +What the level asked for: Decompress a nested hexdump. +Logic used: *Used # ssh bandit12@bandit.labs.overthewire.org -p 2220 # with password "7x16WNeHIi5YkIhWsfFIqoognUTyj9Q4". + *# mktemp -d (create a temporary directory) + cp data.txt (copy the file) + cd (move to tmp directory using (cd)) + mv data.txt data (rename the file simpler by (mv)) + xxd -r data (xxd -r reverses a hexdump in binary) # + *After this use (file) to check for ASCII TXT if not then use recursive decompression with tools like gzip/tar/bbzip2 to extract nested files. + (cat) is used to read the file that shows ASCII TXT on using (file) on it. + + +#LEVEL 13 +What the level asked for: Log in as bandit14 using an SSH private key. +Logic used: *Used # ssh bandit13@bandit.labs.overthewire.org -p 2220 # with password "FO5dwFsc0cbaIiH0h8J2eUks2vdTDwAn". + *WAS NOT ABLE TO DO THIS BECAUSE EVERYTHING WAS RESULTING IN PERMISSION DENIED. + +#LEVEL 14 +What the level asked for: Submit the current level's password to port 30000 on localhost. +Logic used: *Used # ssh bandit14@bandit.labs.overthewire.org -p 2220 # with password "MU4VWeTyJk8ROof1qqmcBPaLh7lDCPvS". + *# cat /etc/bandit_pass/bandit14 | nc localhost 30000 # + *nc (netcat) sends the password to port 30000 + +#LEVEL 15 +What the level asked for: Submit the password to port 30001 using SSL encryption. +Logic used: *Used # ssh bandit15@bandit.labs.overthewire.org -p 2220 # with password "8xCjnmgoKbGLhHFAZlGE5Tmu4M2tKJQo". + *# cat /etc/bandit_pass/bandit15 | openssl s_client -connect localhost:30001 -ign_eof # + *(openssl s_client) establishes an SSL connection. + (-ign_eof) keeps the connection open until the server responds. + From 00ed07eb04e009dc686605a25896dc220120896b Mon Sep 17 00:00:00 2001 From: vedantlohare Date: Tue, 13 May 2025 23:54:53 +0530 Subject: [PATCH 2/2] Task2 --- Dockerfile | 17 +++++ Inventory.h | 60 ++++++++++++++++++ UserUtils.h | 27 ++++++++ content.h | 36 +++++++++++ inventory.txt | 41 +++++++++++++ main.cpp | 167 ++++++++++++++++++++++++++++++++++++++++++++++++++ movie.h | 59 ++++++++++++++++++ tvshows.h | 64 +++++++++++++++++++ user.h | 136 ++++++++++++++++++++++++++++++++++++++++ vedant.txt | 1 + 10 files changed, 608 insertions(+) create mode 100644 Dockerfile create mode 100644 Inventory.h create mode 100644 UserUtils.h create mode 100644 content.h create mode 100644 inventory.txt create mode 100644 main.cpp create mode 100644 movie.h create mode 100644 tvshows.h create mode 100644 user.h create mode 100644 vedant.txt diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..0a81fcd --- /dev/null +++ b/Dockerfile @@ -0,0 +1,17 @@ +# Use an official GCC image +FROM gcc:latest + +# Set working directory +WORKDIR /app + +# Copy source files into the container +COPY . . + +# Create users directory if not present +RUN mkdir -p users + +# Compile the project +RUN g++ -std=c++17 -o netflix main.cpp + +# Set the entrypoint to run the CLI +CMD ["./netflix"] diff --git a/Inventory.h b/Inventory.h new file mode 100644 index 0000000..980924c --- /dev/null +++ b/Inventory.h @@ -0,0 +1,60 @@ +#ifndef INVENTORY_H +#define INVENTORY_H + +#include "movie.h" +#include "tvshows.h" +#include +#include + +class Inventory { +private: + vector contents; + +public: + ~Inventory() { + for (auto c : contents) delete c; + } + + void addContent(Content* c) { + contents.push_back(c); + } + + void displayAll() const { + for (const auto& c : contents) + c->display(); + } + + void displayByGenre(const string& genre) const { + for (const auto& c : contents) + if (c->getGenre() == genre) + c->display(); + } + + Content* searchByTitle(const string& title) { + for (auto& c : contents) + if (c->getTitle() == title) + return c; + return nullptr; + } + + void saveToFile(const string& filename) { + ofstream file(filename); + for (const auto& c : contents) + file << c->serialize() << "\n"; + file.close(); + } + + void loadFromFile(const string& filename) { + ifstream file(filename); + string line; + while (getline(file, line)) { + if (line.find("Movie|") == 0) + contents.push_back(Movie::deserialize(line)); + else if (line.find("TVShow|") == 0) + contents.push_back(TVShow::deserialize(line)); + } + file.close(); + } +}; + +#endif diff --git a/UserUtils.h b/UserUtils.h new file mode 100644 index 0000000..08da15d --- /dev/null +++ b/UserUtils.h @@ -0,0 +1,27 @@ +#ifndef USER_UTILS_H +#define USER_UTILS_H + +#include "user.h" +#include + +namespace fs = std::filesystem; + +inline bool userExists(const string& username) { + return fs::exists("users/" + username + ".txt"); +} + +inline User* loadUser(const string& username) { + ifstream file("users/" + username + ".txt"); + string line; + getline(file, line); + file.close(); + return User::deserialize(line); +} + +inline void saveUser(User* user) { + ofstream file("users/" + user->getUsername() + ".txt"); + file << user->serialize(); + file.close(); +} + +#endif diff --git a/content.h b/content.h new file mode 100644 index 0000000..5c10ad2 --- /dev/null +++ b/content.h @@ -0,0 +1,36 @@ + +#ifndef CONTENT_H +#define CONTENT_H + +#include +using namespace std; + +class Content { +protected: + string title; + string genre; + float rating; + bool is_rented; + bool is_purchased; + +public: + Content(string t, string g, float r) : title(t), genre(g), rating(r), is_rented(false), is_purchased(false) {} + + virtual void display() const = 0; + virtual float getRentCost() const = 0; + virtual float getPurchaseCost() const = 0; + + string getTitle() const { return title; } + string getGenre() const { return genre; } + float getRating() const { return rating; } + bool getIsRented() const { return is_rented; } + bool getIsPurchased() const { return is_purchased; } + + void setRented(bool val) { is_rented = val; } + void setPurchased(bool val) { is_purchased = val; } + + virtual string serialize() const = 0; + virtual ~Content() {} +}; + +#endif diff --git a/inventory.txt b/inventory.txt new file mode 100644 index 0000000..7ad1809 --- /dev/null +++ b/inventory.txt @@ -0,0 +1,41 @@ +Movie|The Matrix|Sci-Fi|8.7|0|0|136|4.99|14.99 +Movie|Inception|Sci-Fi|8.8|0|0|148|5.99|15.99 +Movie|Interstellar|Adventure|8.6|0|0|169|6.49|16.99 +Movie|The Dark Knight|Action|9.0|0|0|152|5.49|14.49 +Movie|Pulp Fiction|Crime|8.9|0|0|154|4.49|13.99 +Movie|The Godfather|Crime|9.2|0|0|175|5.99|15.49 +Movie|The Shawshank Redemption|Drama|9.3|0|0|142|5.99|14.99 +Movie|Forrest Gump|Drama|8.8|0|0|144|4.99|13.49 +Movie|Avengers: Endgame|Action|8.4|0|0|181|6.99|17.99 +Movie|Parasite|Thriller|8.6|0|0|132|5.49|14.49 +Movie|La La Land|Romance|8.0|0|0|128|3.99|11.99 +Movie|Spirited Away|Animation|8.6|0|0|125|4.49|12.49 +Movie|The Lion King|Animation|8.5|0|0|88|3.99|9.99 +Movie|Joker|Drama|8.4|0|0|122|5.99|13.99 +Movie|Tenet|Sci-Fi|7.5|0|0|150|4.99|12.99 +Movie|Gladiator|Action|8.5|0|0|155|5.49|13.99 +Movie|Django Unchained|Western|8.4|0|0|165|4.99|13.49 +Movie|Titanic|Romance|7.8|0|0|195|4.49|12.49 +Movie|The Social Network|Drama|7.7|0|0|120|3.99|10.99 +Movie|1917|War|8.3|0|0|119|4.99|13.99 + +TVShow|Stranger Things|Horror|8.9|0|0|4|8|3.99|12.99 +TVShow|Breaking Bad|Crime|9.5|0|0|5|13|4.99|14.99 +TVShow|Friends|Comedy|8.9|0|0|10|24|3.49|9.99 +TVShow|Game of Thrones|Fantasy|9.3|0|0|8|10|5.99|18.99 +TVShow|The Office|Comedy|8.8|0|0|9|22|3.49|9.99 +TVShow|Money Heist|Thriller|8.2|0|0|5|10|4.99|13.99 +TVShow|The Mandalorian|Sci-Fi|8.7|0|0|3|8|4.99|12.99 +TVShow|Sherlock|Mystery|9.1|0|0|4|3|3.99|11.99 +TVShow|Dark|Sci-Fi|8.8|0|0|3|8|4.99|12.49 +TVShow|Narcos|Crime|8.8|0|0|3|10|4.49|11.99 +TVShow|Brooklyn Nine-Nine|Comedy|8.4|0|0|8|20|3.49|9.49 +TVShow|Black Mirror|Sci-Fi|8.8|0|0|5|6|4.99|11.99 +TVShow|The Boys|Superhero|8.7|0|0|3|8|4.49|12.49 +TVShow|Peaky Blinders|Drama|8.8|0|0|6|6|4.49|13.99 +TVShow|The Witcher|Fantasy|8.1|0|0|2|8|4.99|13.49 +TVShow|Lucifer|Fantasy|8.2|0|0|6|10|3.99|10.99 +TVShow|How I Met Your Mother|Comedy|8.3|0|0|9|22|3.49|9.99 +TVShow|Rick and Morty|Animation|9.2|0|0|5|10|3.99|11.99 +TVShow|House of the Dragon|Fantasy|8.5|0|0|1|10|5.99|14.99 +TVShow|Squid Game|Thriller|8.0|0|0|1|9|4.49|12.49 diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..dbbac56 --- /dev/null +++ b/main.cpp @@ -0,0 +1,167 @@ +#include +#include +#include +#include "Inventory.h" +#include "user.h" +#include "UserUtils.h" + +using namespace std; +namespace fs = std::filesystem; + +const string ADMIN_USERNAME = "admin"; +const string ADMIN_PASSWORD = "admin123"; // For demo + +void userMenu(User* user, Inventory& inventory) { + int choice; + while (true) { + cout << "\nUSER MENU - " << user->getUsername() << "\n"; + cout << "1. Browse all content\n2. Search by title\n3. Rent\n4. Purchase\n5. Return\n6. View rented\n7. View purchased\n8. Charges due\n9. Logout\nChoice: "; + cin >> choice; + cin.ignore(); + + if (choice == 1) { + inventory.displayAll(); + } else if (choice == 2) { + string title; + cout << "Enter title: "; + getline(cin, title); + Content* c = inventory.searchByTitle(title); + if (c) c->display(); + else cout << "Not found.\n"; + } else if (choice == 3) { + string title; + cout << "Enter title to rent: "; + getline(cin, title); + Content* c = inventory.searchByTitle(title); + if (c) user->rent(c); + else cout << "Not found.\n"; + } else if (choice == 4) { + string title; + cout << "Enter title to purchase: "; + getline(cin, title); + Content* c = inventory.searchByTitle(title); + if (c) user->purchase(c); + else cout << "Not found.\n"; + } else if (choice == 5) { + string title; + cout << "Enter title to return: "; + getline(cin, title); + Content* c = inventory.searchByTitle(title); + if (c) user->returnItem(c); + else cout << "Not found.\n"; + } else if (choice == 6) { + user->viewRented(); + } else if (choice == 7) { + user->viewPurchased(); + } else if (choice == 8) { + user->viewCharges(); + } else if (choice == 9) { + saveUser(user); + cout << "Logged out.\n"; + break; + } else { + cout << "Invalid choice.\n"; + } + } +} + +void adminMenu(Inventory& inventory) { + int choice; + while (true) { + cout << "\nADMIN MENU\n"; + cout << "1. Add Movie\n2. Add TV Show\n3. Remove Content\n4. View All Content\n5. Logout\nChoice: "; + cin >> choice; + cin.ignore(); + + if (choice == 1) { + string title, genre; + float rating, rent, purchase; + int duration; + cout << "Enter title, genre, rating, duration, rent cost, purchase cost:\n"; + getline(cin, title); getline(cin, genre); + cin >> rating >> duration >> rent >> purchase; cin.ignore(); + inventory.addContent(new Movie(title, genre, rating, duration, rent, purchase)); + cout << "Movie added.\n"; + } else if (choice == 2) { + string title, genre; + float rating, rent, purchase; + int seasons, eps; + cout << "Enter title, genre, rating, seasons, eps/season, rent/season, purchase/season:\n"; + getline(cin, title); getline(cin, genre); + cin >> rating >> seasons >> eps >> rent >> purchase; cin.ignore(); + inventory.addContent(new TVShow(title, genre, rating, seasons, eps, rent, purchase)); + cout << "TV Show added.\n"; + } else if (choice == 3) { + string title; + cout << "Enter title to remove: "; + getline(cin, title); + // Simplified: just mark as not available, or skip (you can implement actual removal later) + cout << "Feature not implemented.\n"; + } else if (choice == 4) { + inventory.displayAll(); + } else if (choice == 5) { + cout << "Admin logged out.\n"; + break; + } else { + cout << "Invalid choice.\n"; + } + } +} + +int main() { + fs::create_directory("users"); + + Inventory inventory; + inventory.loadFromFile("inventory.txt"); + + while (true) { + int option; + cout << "\n--- NETFLIX CLI SYSTEM ---\n"; + cout << "1. User Sign Up\n2. User Login\n3. Admin Login\n4. Exit\nChoice: "; + cin >> option; + cin.ignore(); + + if (option == 1) { + string uname; + cout << "Enter new username: "; + getline(cin, uname); + if (userExists(uname)) { + cout << "Username already exists.\n"; + } else { + User* u = new User(uname); + saveUser(u); + cout << "Sign-up successful. You can now log in.\n"; + } + } else if (option == 2) { + string uname; + cout << "Enter username: "; + getline(cin, uname); + if (!userExists(uname)) { + cout << "User not found.\n"; + } else { + User* user = loadUser(uname); + cout << "Welcome " << user->getUsername() << "!\n"; + userMenu(user, inventory); + } + } else if (option == 3) { + string uname, pass; + cout << "Enter admin username: "; + getline(cin, uname); + cout << "Enter admin password: "; + getline(cin, pass); + if (uname == ADMIN_USERNAME && pass == ADMIN_PASSWORD) { + adminMenu(inventory); + } else { + cout << "Invalid admin credentials.\n"; + } + } else if (option == 4) { + inventory.saveToFile("inventory.txt"); + cout << "Exiting...\n"; + break; + } else { + cout << "Invalid input.\n"; + } + } + + return 0; +} diff --git a/movie.h b/movie.h new file mode 100644 index 0000000..545fcab --- /dev/null +++ b/movie.h @@ -0,0 +1,59 @@ +#ifndef MOVIE_H +#define MOVIE_H + +#include "content.h" +#include +#include + +class Movie : public Content { +private: + int duration; + float rent_cost; + float purchase_cost; + +public: + Movie(string t, string g, float r, int d, float rent, float purchase) + : Content(t, g, r), duration(d), rent_cost(rent), purchase_cost(purchase) {} + + void display() const override { + cout << "Movie: " << title << " | Genre: " << genre << " | Rating: " << rating + << " | Duration: " << duration << " mins | Rent: $" << rent_cost + << " | Purchase: $" << purchase_cost << endl; + } + + float getRentCost() const override { return rent_cost; } + float getPurchaseCost() const override { return purchase_cost; } + + string serialize() const override { + stringstream ss; + ss << "Movie|" << title << "|" << genre << "|" << rating << "|" << duration + << "|" << rent_cost << "|" << purchase_cost << "|" << is_rented << "|" << is_purchased; + return ss.str(); + } + + static Movie* deserialize(const string& line) { + stringstream ss(line); + string type, t, g; + float r; + int d; + float rent, purchase; + bool rented, purchased; + + getline(ss, type, '|'); + getline(ss, t, '|'); + getline(ss, g, '|'); + ss >> r; ss.ignore(); + ss >> d; ss.ignore(); + ss >> rent; ss.ignore(); + ss >> purchase; ss.ignore(); + ss >> rented; ss.ignore(); + ss >> purchased; + + Movie* m = new Movie(t, g, r, d, rent, purchase); + m->setRented(rented); + m->setPurchased(purchased); + return m; + } +}; + +#endif diff --git a/tvshows.h b/tvshows.h new file mode 100644 index 0000000..3352af2 --- /dev/null +++ b/tvshows.h @@ -0,0 +1,64 @@ +#ifndef TVSHOW_H +#define TVSHOW_H + +#include "content.h" +#include +#include + +class TVShow : public Content { +private: + int seasons; + int episodes_per_season; + float rent_cost_per_season; + float purchase_cost_per_season; + +public: + TVShow(string t, string g, float r, int s, int eps, float rent, float purchase) + : Content(t, g, r), seasons(s), episodes_per_season(eps), + rent_cost_per_season(rent), purchase_cost_per_season(purchase) {} + + void display() const override { + cout << "TV Show: " << title << " | Genre: " << genre << " | Rating: " << rating + << " | Seasons: " << seasons << " | Episodes/Season: " << episodes_per_season + << " | Rent/Season: $" << rent_cost_per_season + << " | Purchase/Season: $" << purchase_cost_per_season << endl; + } + + float getRentCost() const override { return seasons * rent_cost_per_season; } + float getPurchaseCost() const override { return seasons * purchase_cost_per_season; } + + string serialize() const override { + stringstream ss; + ss << "TVShow|" << title << "|" << genre << "|" << rating << "|" << seasons + << "|" << episodes_per_season << "|" << rent_cost_per_season + << "|" << purchase_cost_per_season << "|" << is_rented << "|" << is_purchased; + return ss.str(); + } + + static TVShow* deserialize(const string& line) { + stringstream ss(line); + string type, t, g; + float r; + int s, eps; + float rent, purchase; + bool rented, purchased; + + getline(ss, type, '|'); + getline(ss, t, '|'); + getline(ss, g, '|'); + ss >> r; ss.ignore(); + ss >> s; ss.ignore(); + ss >> eps; ss.ignore(); + ss >> rent; ss.ignore(); + ss >> purchase; ss.ignore(); + ss >> rented; ss.ignore(); + ss >> purchased; + + TVShow* show = new TVShow(t, g, r, s, eps, rent, purchase); + show->setRented(rented); + show->setPurchased(purchased); + return show; + } +}; + +#endif diff --git a/user.h b/user.h new file mode 100644 index 0000000..1783104 --- /dev/null +++ b/user.h @@ -0,0 +1,136 @@ +#ifndef USER_H +#define USER_H + +#include "content.h" +#include +#include +#include +#include +#include +#include + +using namespace std; + +class User { +private: + string username; + vector rented_titles; + vector purchased_titles; + float charges_due; + +public: + // Constructor + User(const string& uname) : username(uname), charges_due(0.0f) {} + + // Getters + string getUsername() const { return username; } + float getChargesDue() const { return charges_due; } + + // Rent content + void rent(Content* item) { + if (item->getIsRented()) { + cout << "This item is already rented.\n"; + return; + } + item->setRented(true); + rented_titles.push_back(item->getTitle()); + charges_due += item->getRentCost(); + cout << "Rented successfully. $" << item->getRentCost() << " added to charges.\n"; + } + + // Purchase content + void purchase(Content* item) { + if (item->getIsPurchased()) { + cout << "This item is already purchased.\n"; + return; + } + item->setPurchased(true); + purchased_titles.push_back(item->getTitle()); + charges_due += item->getPurchaseCost(); + cout << "Purchased successfully. $" << item->getPurchaseCost() << " added to charges.\n"; + } + + // Return rented content + void returnItem(Content* item) { + if (!item->getIsRented()) { + cout << "This item was not rented.\n"; + return; + } + item->setRented(false); + auto it = find(rented_titles.begin(), rented_titles.end(), item->getTitle()); + if (it != rented_titles.end()) { + rented_titles.erase(it); + } + cout << "Returned successfully.\n"; + } + + // View currently rented titles + void viewRented() const { + cout << "Rented Items:\n"; + if (rented_titles.empty()) { + cout << "None\n"; + } else { + for (const auto& title : rented_titles) + cout << "- " << title << endl; + } + } + + // View purchased titles + void viewPurchased() const { + cout << "Purchased Items:\n"; + if (purchased_titles.empty()) { + cout << "None\n"; + } else { + for (const auto& title : purchased_titles) + cout << "- " << title << endl; + } + } + + // View due charges + void viewCharges() const { + cout << "Total Charges Due: $" << charges_due << endl; + } + + // Convert to string for file storage + string serialize() const { + stringstream ss; + ss << username << "|" << charges_due << "|"; + + for (const auto& r : rented_titles) + ss << r << ","; + ss << "|"; + + for (const auto& p : purchased_titles) + ss << p << ","; + return ss.str(); + } + + // Restore from file + static User* deserialize(const string& line) { + stringstream ss(line); + string uname, charge_str, rented_str, purchased_str; + + getline(ss, uname, '|'); + getline(ss, charge_str, '|'); + getline(ss, rented_str, '|'); + getline(ss, purchased_str, '|'); + + User* u = new User(uname); + u->charges_due = stof(charge_str); + + stringstream rented_stream(rented_str); + string title; + while (getline(rented_stream, title, ',')) { + if (!title.empty()) u->rented_titles.push_back(title); + } + + stringstream purchased_stream(purchased_str); + while (getline(purchased_stream, title, ',')) { + if (!title.empty()) u->purchased_titles.push_back(title); + } + + return u; + } +}; + +#endif diff --git a/vedant.txt b/vedant.txt new file mode 100644 index 0000000..4de2325 --- /dev/null +++ b/vedant.txt @@ -0,0 +1 @@ +vedant|148||Inception, \ No newline at end of file