[C++] Модули для работы с файлами Стима

Для тех, кто хочет сделать мир лучше.
Сообщение
Автор
Аватара пользователя
andreil
Разработчик
Разработчик
Сообщения: 781
Зарегистрирован: 14.08.2006
Откуда: Светлогорск, Беларусь
Поблагодарили: 2 раза
Контактная информация:

#1 Сообщение 06.07.2011, 17:16

В рамках разработки серверов решил открыть практически все исходники (кроме самих серверов, да и это скорее всего временно).
Для компиляции требуется библиотека OpenSSL (пока не требуется, так как используется только для серверов. Поэтому их проекта можно исключить модуль RSAMod(.h;.cpp))
Имеющиеся библиотеки:
  1. BLOBFile - работа с BLOB-файлами Steam'а (все файлы *.blob, а так же Content Description Record);
  2. CDRFile - работа с Content Description Record;
  3. GCFFile - работа с файлами GCF/NCF;
  4. PKGFile - работа с файлами PKG (в них хранится клиент на контент-серверах);
  5. PAKFile - работа с PAK-файлами (архивы Quake и Half-Life);
  6. VPKFile - работа с VPK-файлами (L4D, Portal 2).
Синим цветом помечены уже написанные библиотеки.
Оранжевым цветом помечены библиотеки, находящиеся на доработке.
Красным цветом помечены библиотеки, в данный момент не реализованные на C++, но имеющие реализаци. на Delphi. Они будут переписаны в ближайшее время.

Сопутствующие библиотеки:
  1. Csocket - слегка модифицированная библиотека-обертка над сокетами от пользователя fire666;
  2. RSAMod - реализует работу с сигнатурами для сети Steam'а (требует OpenSSL);
  3. Stream - реализация файлового потока (надстройка на API операционной системы);
  4. functions - некоторые полезные функции;
  5. Patcher - патчер для Steam.exe и Steam.dll (замена адресов серверов и ключей шифрования).
Список будет постоянно обновляться и увеличиваться по мере необходимости файлов.

PS: Приму замечания и предложения по коду, так как с плюсах я пока не очень :blush:
Аттач пухлый из-за файла с CDR ;)

Добавлено спустя 1 минуту 55 секунд:
Файл проекта приведен для примера и не компилируем (пока не будут вырезаны зависимости для файлов .\Servers, пока в паблик не выкладываемых).

Для ленивых - статические библиотеки (OpenSLL и ZLib) для платформы x86 можно скачать здесь
Вложения
upd_1.zip
Еще один апдейт
(32.08 КБ) 263 скачивания
upd_1.zip
Еще один апдейт
(32.08 КБ) 263 скачивания
upd_0.zip
Небольшой апдейт
(10.69 КБ) 230 скачиваний
upd_0.zip
Небольшой апдейт
(10.69 КБ) 230 скачиваний
Servers.zip
(1.72 МБ) 272 скачивания
Servers.zip
(1.72 МБ) 272 скачивания
[url=svn://forum.csmania.ru/andreil]Репозиторий с моими проектами[/url]
Занимаюсь переносом всех своих библиотек на С++, а так же созданием их кроссплатформенных версий.
В команду переводчиков манги "Ah! My Goddess!" требуются переводчики с английского и тайперы (последних можем обучить, главное - желание).

Fire666
Эксперты no-Steam
Эксперты no-Steam
Сообщения: 2600
Зарегистрирован: 15.02.2007
Откуда: Москва
Благодарил (а): 2 раза
Поблагодарили: 43 раза
Контактная информация:

#2 Сообщение 06.07.2011, 17:49

Интересно, сейчас гляну.

Аватара пользователя
andreil
Разработчик
Разработчик
Сообщения: 781
Зарегистрирован: 14.08.2006
Откуда: Светлогорск, Беларусь
Поблагодарили: 2 раза
Контактная информация:

#3 Сообщение 06.07.2011, 22:28

UP:
  1. [ADD] Модуль CDRFile;
  2. [FIX] BLOBFile (в конструкторе CBLOBFile(CStream *stream) поток удалялся, чего делать не следует).
[url=svn://forum.csmania.ru/andreil]Репозиторий с моими проектами[/url]
Занимаюсь переносом всех своих библиотек на С++, а так же созданием их кроссплатформенных версий.
В команду переводчиков манги "Ah! My Goddess!" требуются переводчики с английского и тайперы (последних можем обучить, главное - желание).

Аватара пользователя
andreil
Разработчик
Разработчик
Сообщения: 781
Зарегистрирован: 14.08.2006
Откуда: Светлогорск, Беларусь
Поблагодарили: 2 раза
Контактная информация:

#4 Сообщение 08.07.2011, 22:21

UP:
  1. [FIX] BLOBFile, RSAMod;
  2. [ADD]GCFFIle, PKGFile, Patcher;
[url=svn://forum.csmania.ru/andreil]Репозиторий с моими проектами[/url]
Занимаюсь переносом всех своих библиотек на С++, а так же созданием их кроссплатформенных версий.
В команду переводчиков манги "Ah! My Goddess!" требуются переводчики с английского и тайперы (последних можем обучить, главное - желание).

Fire666
Эксперты no-Steam
Эксперты no-Steam
Сообщения: 2600
Зарегистрирован: 15.02.2007
Откуда: Москва
Благодарил (а): 2 раза
Поблагодарили: 43 раза
Контактная информация:

#5 Сообщение 12.07.2011, 13:26

andreil, еще вопрос по поводу скачивания контента с серверов.

Скажем насчет скачивания самого стима все ясно, там используется загрузка pkg файлов.

А что насчет HldsUpdateTool.exe, SteamGameUpdater.dll, CAS.exe, CAC.exe и других стим утилит, скачивающих обновление со стима ?

Да и еще, а как получить список ключей BLOB файла ?
Я пробовал, такой код. но ничего не вышло:

Код: Выделить всё

	CBLOBFile *pBlobVersion = new CBLOBFile( "steamvesrion.blob" );

	CBLOBNode *pRootBlob = pBlobVersion->RootNode();

	printf( "Root Node Name: %s\n",  pRootBlob->Name() );
	printf( "Count Nodes: %d\n",  pRootBlob->ChildrensCount() );

	for( int i = 0; i < pRootBlob->ChildrensCount(); i++ )
	{
		CBLOBNode *pCuurentNode = pRootBlob->Childrens(i);

		printf( "Node %d Name: %s\n", i,  pCuurentNode->Name() );

		if( pCuurentNode->ChildrensCount() )
		{
			for( int j = 0; j < pCuurentNode->ChildrensCount(); j++ )
			{
				CBLOBNode *pSubCuurentNode = pCuurentNode->Childrens(j);

				printf( "Node %d, Sub: %d Name: %s\n", i, j, pSubCuurentNode->Name() );
			}
		}
	}
Точнее pSubCuurentNode пишет имя ключа, а все остальные ноды нет.

Аватара пользователя
andreil
Разработчик
Разработчик
Сообщения: 781
Зарегистрирован: 14.08.2006
Откуда: Светлогорск, Беларусь
Поблагодарили: 2 раза
Контактная информация:

#6 Сообщение 12.07.2011, 16:29

Насчет скачивания - не знаю. Вот закончу колупаться со стационарником (перегоняю 1Тб винт из NTFS в Ext3 с буффром на 40Гб :( ) и посмотрю - просто еще не имел дел с этими тулзами.
Насчет BLOB - имена у данного файла (как и у CDR'а) идут в двоичном формате, а не в текстовом. То есть имя имеет вид "\x01\x00\x00\x00" и подобные (всегда ровно 4 байта). Для получения узла по такому имени юзаю следующее:

Код: Выделить всё

CBLOBNode *CBLOBNode::GetNodeIdx(UINT32 NodeIdxName)
{
	return GetNode((char*)&NodeIdxName);
}
Если надо такое имя вывести, то попробуй так:

Код: Выделить всё

printf( "Node %d Name: %h\n", i,  *((UINT32)pCuurentNode->Name()) );
[url=svn://forum.csmania.ru/andreil]Репозиторий с моими проектами[/url]
Занимаюсь переносом всех своих библиотек на С++, а так же созданием их кроссплатформенных версий.
В команду переводчиков манги "Ah! My Goddess!" требуются переводчики с английского и тайперы (последних можем обучить, главное - желание).

Fire666
Эксперты no-Steam
Эксперты no-Steam
Сообщения: 2600
Зарегистрирован: 15.02.2007
Откуда: Москва
Благодарил (а): 2 раза
Поблагодарили: 43 раза
Контактная информация:

#7 Сообщение 12.07.2011, 16:44

Что-то опять не то.
Правильно ли я понял, что если NameLen() = 4, то это не имя, а ID нода ?

В таком случае, почему не работает:

Код: Выделить всё

		if( !pCuurentNode->ChildrensCount() && pCuurentNode->NameLen() == 4 )
		{
			CBLOBNode *pChildrenNode = pCuurentNode->GetNodeByIdx( (UINT32)pCuurentNode->Name( ) );

			printf( "Children Node Name Len: %d\n",  pChildrenNode->NameLen() );			
		}
И еще, а как узнать тип используемых данных ?

п.с.

Код: Выделить всё

printf( "Node %d Name: %h\n", i,  *((UINT32)pCuurentNode->Name()) );
не компилится: error C2100: недопустимое косвенное обращение

а

Код: Выделить всё

printf( "Node %d Name: %x\n", i, (UINT32)pCuurentNode->Name() );
Выдает:
Node 0 Name: 343598
Node 1 Name: 3435e0
Node 2 Name: 343628
Node 3 Name: 343670
Node 4 Name: 3436b8
Node 5 Name: 343700
Node 6 Name: 343748
Node 7 Name: 343790
Node 8 Name: 344960
Node 9 Name: 3449a8
Node 10 Name: 344a00
Node 11 Name: 344a48
Node 12 Name: 344a90
Node 13 Name: 344ad8
Node 14 Name: 344b28
Node 15 Name: 344c60
А вот pSubCuurentNode содержит имена в виде строк.
Node 13 Name:
Node 14 Name: ♫
Node 14, Sub: 0 Name: cac
Node 14, Sub: 1 Name: cas
Node 14, Sub: 2 Name: SteamGameUpdater
Node 15 Name: ☼

Аватара пользователя
andreil
Разработчик
Разработчик
Сообщения: 781
Зарегистрирован: 14.08.2006
Откуда: Светлогорск, Беларусь
Поблагодарили: 2 раза
Контактная информация:

#8 Сообщение 12.07.2011, 18:19

Fire666
Моя вина - забыл "*", а ты и не заметил :blush:

Код: Выделить всё

	CBLOBFile *blob = new CBLOBFile(".\\files\\versions.blob");
	CBLOBNode *RootNode = blob->RootNode();
	for (UINT32 i=0 ; i<RootNode->ChildrensCount() ; i++)
	{
		CBLOBNode *child = RootNode->Childrens(i);
		printf("Node #%i. NameLen: %i Name: %x\n", i, child->NameLen(), *((UINT32*)child->Name()));
	}
	delete blob;
Выдает:

Код: Выделить всё

Node #0. NameLen: 4 Name: 0
Node #1. NameLen: 4 Name: 1
Node #2. NameLen: 4 Name: 2
Node #3. NameLen: 4 Name: 3
Node #4. NameLen: 4 Name: 4
Node #5. NameLen: 4 Name: 5
Node #6. NameLen: 4 Name: 6
Node #7. NameLen: 4 Name: 7
Node #8. NameLen: 4 Name: 9
Node #9. NameLen: 4 Name: a
Node #10. NameLen: 4 Name: b
Node #11. NameLen: 4 Name: c
Node #12. NameLen: 4 Name: d
Node #13. NameLen: 4 Name: e
Node #14. NameLen: 4 Name: f
Насчет типов данных - они нигде не прописаны и привязаны только к имени нода, а так же пути к нему (посмотри CDRFile.cpp, поймешь).
Правильно ли я понял, что если NameLen() = 4, то это не имя, а ID нода ?
Не обязательно. Это просто строка (которая не обязательно текстовая).
И да, у некоторых нодов строковые значения, но есть и bool и int16 и int32 ;)
[url=svn://forum.csmania.ru/andreil]Репозиторий с моими проектами[/url]
Занимаюсь переносом всех своих библиотек на С++, а так же созданием их кроссплатформенных версий.
В команду переводчиков манги "Ah! My Goddess!" требуются переводчики с английского и тайперы (последних можем обучить, главное - желание).

Fire666
Эксперты no-Steam
Эксперты no-Steam
Сообщения: 2600
Зарегистрирован: 15.02.2007
Откуда: Москва
Благодарил (а): 2 раза
Поблагодарили: 43 раза
Контактная информация:

#9 Сообщение 12.07.2011, 19:09

Значит получить количество и типы данных из узла невозможно ?

Иными словами, необходимо заранее знать параметры нодов, что бы получить нормальные данные ?

Код: Выделить всё

	CBLOBFile *pBlobVersion = new CBLOBFile( "steamvesrion.blob" );

	CBLOBNode *pRootBlob = pBlobVersion->RootNode();

	printf( "Root Node Name: %d\n",  pRootBlob->Name() );
	printf( "Count Nodes: %d\n",  pRootBlob->ChildrensCount() );

	for( int i = 0; i < pRootBlob->ChildrensCount(); i++ )
	{
		CBLOBNode *pCuurentNode = pRootBlob->Childrens(i);

		UINT32 nodeid = *((UINT32*)pCuurentNode->Name());
		UINT32 nodedata = *((UINT32*)pCuurentNode->Data());

		printf( "Node: %d, Name: %d\n", i, nodeid );

		switch( nodeid )
		{
		case 7:
			printf( "App: %s\n", pCuurentNode->Data() );
			break;
		case 9:
			printf( "App: %s\n", pCuurentNode->Data() );
			break;
		case 11:
			printf( "App: %s\n", pCuurentNode->Data() );
			break;
		case 13:
			printf( "App: %s\n", pCuurentNode->Data() );
			break;
		case 14:
			break;
		default:
	//		printf( "Version: %d\n", nodedata );
			break;
		}

		if( pCuurentNode->ChildrensCount() )
		{
			for( int j = 0; j < pCuurentNode->ChildrensCount(); j++ )
			{
				CBLOBNode *pSubCurrentNode = pCuurentNode->Childrens(j);

				printf( "Node %d, Sub: %d Name: %s\n", i, j, pSubCurrentNode->Name() );
			}
		}
	}

Аватара пользователя
andreil
Разработчик
Разработчик
Сообщения: 781
Зарегистрирован: 14.08.2006
Откуда: Светлогорск, Беларусь
Поблагодарили: 2 раза
Контактная информация:

#10 Сообщение 12.07.2011, 23:35

Fire666 писал(а):Значит получить количество и типы данных из узла невозможно ?

Иными словами, необходимо заранее знать параметры нодов, что бы получить нормальные данные ?
Все именно так и есть.
[url=svn://forum.csmania.ru/andreil]Репозиторий с моими проектами[/url]
Занимаюсь переносом всех своих библиотек на С++, а так же созданием их кроссплатформенных версий.
В команду переводчиков манги "Ah! My Goddess!" требуются переводчики с английского и тайперы (последних можем обучить, главное - желание).

Аватара пользователя
GanGSISoft
Полковник
Полковник
Сообщения: 1430
Зарегистрирован: 27.03.2008
Откуда: Бацькаўшчына
Благодарил (а): 2 раза
Поблагодарили: 3 раза
Контактная информация:

#11 Сообщение 25.07.2011, 22:09

Спасибо, хотел на linux попробовать сделать программу для gcf и cdr, вот может руки дойдут и сделаю

Аватара пользователя
andreil
Разработчик
Разработчик
Сообщения: 781
Зарегистрирован: 14.08.2006
Откуда: Светлогорск, Беларусь
Поблагодарили: 2 раза
Контактная информация:

#12 Сообщение 25.07.2011, 23:09

GanGSISoft
Под никсы пока не портировал, ибо надо сперва сделать в знакомой среде :blush: Пока там юзается WinAPI. Если будешь переделывать под никсы, то просьба - сделай переключение платформозависимых участков кода директивой компилятора и выложи рабочие файлы ;)
[url=svn://forum.csmania.ru/andreil]Репозиторий с моими проектами[/url]
Занимаюсь переносом всех своих библиотек на С++, а так же созданием их кроссплатформенных версий.
В команду переводчиков манги "Ah! My Goddess!" требуются переводчики с английского и тайперы (последних можем обучить, главное - желание).

Аватара пользователя
GanGSISoft
Полковник
Полковник
Сообщения: 1430
Зарегистрирован: 27.03.2008
Откуда: Бацькаўшчына
Благодарил (а): 2 раза
Поблагодарили: 3 раза
Контактная информация:

#13 Сообщение 26.07.2011, 20:19

делай переключение платформозависимых участков кода директивой компилятора и выложи рабочие файлы
Я нуб ещё тот, если и сделаю чтобы работало, то очень криво и косо. Думаю ещё повырезаю не нужные функции(патчинг, редактирование gcf и тд, а то там ошибок не мало)

Добавлено спустя 9 минут 54 секунды:
Да и сложно что-то для меня, очень много не совместимостей

Аватара пользователя
andreil
Разработчик
Разработчик
Сообщения: 781
Зарегистрирован: 14.08.2006
Откуда: Светлогорск, Беларусь
Поблагодарили: 2 раза
Контактная информация:

#14 Сообщение 26.07.2011, 23:59

GanGSISoft
И какие там ошибки? Если нашел - пиши сюда, буду исправлять, ибо код проверяется по мере его использования в моих программах, а Сишный вариант юзается пока только в одном проекте, так что ляпов там может быть много.
[url=svn://forum.csmania.ru/andreil]Репозиторий с моими проектами[/url]
Занимаюсь переносом всех своих библиотек на С++, а так же созданием их кроссплатформенных версий.
В команду переводчиков манги "Ah! My Goddess!" требуются переводчики с английского и тайперы (последних можем обучить, главное - желание).

Аватара пользователя
GanGSISoft
Полковник
Полковник
Сообщения: 1430
Зарегистрирован: 27.03.2008
Откуда: Бацькаўшчына
Благодарил (а): 2 раза
Поблагодарили: 3 раза
Контактная информация:

#15 Сообщение 27.07.2011, 01:28

andreil
я имел ввиду что компилятор выдаёт ошибки, из-за того что используется много чего незнакомого для linux, например типы, некоторые классы вроде бы, для меня местами совсем незнакомое, и исправлять тяжело.

Ответить Вложения 3